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: dweis@google.com (Daniel Weis)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <google/protobuf/compiler/java/java_message_builder.h>
36 
37 #include <algorithm>
38 #include <google/protobuf/stubs/hash.h>
39 #include <map>
40 #include <memory>
41 #ifndef _SHARED_PTR_H
42 #include <google/protobuf/stubs/shared_ptr.h>
43 #endif
44 #include <vector>
45 
46 #include <google/protobuf/compiler/java/java_context.h>
47 #include <google/protobuf/compiler/java/java_doc_comment.h>
48 #include <google/protobuf/compiler/java/java_enum.h>
49 #include <google/protobuf/compiler/java/java_extension.h>
50 #include <google/protobuf/compiler/java/java_generator_factory.h>
51 #include <google/protobuf/compiler/java/java_helpers.h>
52 #include <google/protobuf/compiler/java/java_name_resolver.h>
53 #include <google/protobuf/io/coded_stream.h>
54 #include <google/protobuf/io/printer.h>
55 #include <google/protobuf/descriptor.pb.h>
56 #include <google/protobuf/wire_format.h>
57 #include <google/protobuf/stubs/strutil.h>
58 #include <google/protobuf/stubs/substitute.h>
59 
60 namespace google {
61 namespace protobuf {
62 namespace compiler {
63 namespace java {
64 
65 namespace {
GenerateHasBits(const Descriptor * descriptor)66 bool GenerateHasBits(const Descriptor* descriptor) {
67   return SupportFieldPresence(descriptor->file()) ||
68       HasRepeatedFields(descriptor);
69 }
70 
MapValueImmutableClassdName(const Descriptor * descriptor,ClassNameResolver * name_resolver)71 string MapValueImmutableClassdName(const Descriptor* descriptor,
72                                    ClassNameResolver* name_resolver) {
73   const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
74   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
75   return name_resolver->GetImmutableClassName(value_field->message_type());
76 }
77 }  // namespace
78 
MessageBuilderGenerator(const Descriptor * descriptor,Context * context)79 MessageBuilderGenerator::MessageBuilderGenerator(
80     const Descriptor* descriptor, Context* context)
81   : descriptor_(descriptor), context_(context),
82     name_resolver_(context->GetNameResolver()),
83     field_generators_(descriptor, context_) {
84   GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
85       << "Generator factory error: A non-lite message generator is used to "
86          "generate lite messages.";
87 }
88 
~MessageBuilderGenerator()89 MessageBuilderGenerator::~MessageBuilderGenerator() {}
90 
91 void MessageBuilderGenerator::
Generate(io::Printer * printer)92 Generate(io::Printer* printer) {
93   WriteMessageDocComment(printer, descriptor_);
94   if (descriptor_->extension_range_count() > 0) {
95     printer->Print(
96       "public static final class Builder extends\n"
97       "    com.google.protobuf.GeneratedMessage$ver$.ExtendableBuilder<\n"
98       "      $classname$, Builder> implements\n"
99       "    $extra_interfaces$\n"
100       "    $classname$OrBuilder {\n",
101       "classname", name_resolver_->GetImmutableClassName(descriptor_),
102       "extra_interfaces", ExtraBuilderInterfaces(descriptor_),
103       "ver", GeneratedCodeVersionSuffix());
104   } else {
105     printer->Print(
106       "public static final class Builder extends\n"
107       "    com.google.protobuf.GeneratedMessage$ver$.Builder<Builder> implements\n"
108       "    $extra_interfaces$\n"
109       "    $classname$OrBuilder {\n",
110       "classname", name_resolver_->GetImmutableClassName(descriptor_),
111       "extra_interfaces", ExtraBuilderInterfaces(descriptor_),
112       "ver", GeneratedCodeVersionSuffix());
113   }
114   printer->Indent();
115 
116   GenerateDescriptorMethods(printer);
117   GenerateCommonBuilderMethods(printer);
118 
119   if (context_->HasGeneratedMethods(descriptor_)) {
120     GenerateIsInitialized(printer);
121     GenerateBuilderParsingMethods(printer);
122   }
123 
124   // oneof
125   map<string, string> vars;
126   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
127     vars["oneof_name"] = context_->GetOneofGeneratorInfo(
128         descriptor_->oneof_decl(i))->name;
129     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
130         descriptor_->oneof_decl(i))->capitalized_name;
131     vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
132     // oneofCase_ and oneof_
133     printer->Print(vars,
134       "private int $oneof_name$Case_ = 0;\n"
135       "private java.lang.Object $oneof_name$_;\n");
136     // oneofCase() and clearOneof()
137     printer->Print(vars,
138       "public $oneof_capitalized_name$Case\n"
139       "    get$oneof_capitalized_name$Case() {\n"
140       "  return $oneof_capitalized_name$Case.forNumber(\n"
141       "      $oneof_name$Case_);\n"
142       "}\n"
143       "\n"
144       "public Builder clear$oneof_capitalized_name$() {\n"
145       "  $oneof_name$Case_ = 0;\n"
146       "  $oneof_name$_ = null;\n");
147     printer->Print("  onChanged();\n");
148     printer->Print(
149       "  return this;\n"
150       "}\n"
151       "\n");
152   }
153 
154   if (GenerateHasBits(descriptor_)) {
155     // Integers for bit fields.
156     int totalBits = 0;
157     for (int i = 0; i < descriptor_->field_count(); i++) {
158       totalBits += field_generators_.get(descriptor_->field(i))
159           .GetNumBitsForBuilder();
160     }
161     int totalInts = (totalBits + 31) / 32;
162     for (int i = 0; i < totalInts; i++) {
163       printer->Print("private int $bit_field_name$;\n",
164         "bit_field_name", GetBitFieldName(i));
165     }
166   }
167 
168   for (int i = 0; i < descriptor_->field_count(); i++) {
169     printer->Print("\n");
170     field_generators_.get(descriptor_->field(i))
171                      .GenerateBuilderMembers(printer);
172   }
173 
174   if (!PreserveUnknownFields(descriptor_)) {
175     printer->Print(
176       "public final Builder setUnknownFields(\n"
177       "    final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
178       "  return this;\n"
179       "}\n"
180       "\n"
181       "public final Builder mergeUnknownFields(\n"
182       "    final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
183       "  return this;\n"
184       "}\n"
185       "\n");
186   } else {
187     printer->Print(
188       "public final Builder setUnknownFields(\n"
189       "    final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
190       "  return super.setUnknownFields(unknownFields);\n"
191       "}\n"
192       "\n"
193       "public final Builder mergeUnknownFields(\n"
194       "    final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
195       "  return super.mergeUnknownFields(unknownFields);\n"
196       "}\n"
197       "\n");
198   }
199 
200   printer->Print(
201     "\n"
202     "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
203     "full_name", descriptor_->full_name());
204 
205   printer->Outdent();
206   printer->Print("}\n");
207 }
208 
209 // ===================================================================
210 
211 void MessageBuilderGenerator::
GenerateDescriptorMethods(io::Printer * printer)212 GenerateDescriptorMethods(io::Printer* printer) {
213   if (!descriptor_->options().no_standard_descriptor_accessor()) {
214     printer->Print(
215       "public static final com.google.protobuf.Descriptors.Descriptor\n"
216       "    getDescriptor() {\n"
217       "  return $fileclass$.internal_$identifier$_descriptor;\n"
218       "}\n"
219       "\n",
220       "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
221       "identifier", UniqueFileScopeIdentifier(descriptor_));
222   }
223   vector<const FieldDescriptor*> map_fields;
224   for (int i = 0; i < descriptor_->field_count(); i++) {
225     const FieldDescriptor* field = descriptor_->field(i);
226     if (GetJavaType(field) == JAVATYPE_MESSAGE &&
227         IsMapEntry(field->message_type())) {
228       map_fields.push_back(field);
229     }
230   }
231   if (!map_fields.empty()) {
232     printer->Print(
233       "@SuppressWarnings({\"rawtypes\"})\n"
234       "protected com.google.protobuf.MapField internalGetMapField(\n"
235       "    int number) {\n"
236       "  switch (number) {\n");
237     printer->Indent();
238     printer->Indent();
239     for (int i = 0; i < map_fields.size(); ++i) {
240       const FieldDescriptor* field = map_fields[i];
241       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
242       printer->Print(
243         "case $number$:\n"
244         "  return internalGet$capitalized_name$();\n",
245         "number", SimpleItoa(field->number()),
246         "capitalized_name", info->capitalized_name);
247     }
248     printer->Print(
249         "default:\n"
250         "  throw new RuntimeException(\n"
251         "      \"Invalid map field number: \" + number);\n");
252     printer->Outdent();
253     printer->Outdent();
254     printer->Print(
255         "  }\n"
256         "}\n");
257     printer->Print(
258       "@SuppressWarnings({\"rawtypes\"})\n"
259       "protected com.google.protobuf.MapField internalGetMutableMapField(\n"
260       "    int number) {\n"
261       "  switch (number) {\n");
262     printer->Indent();
263     printer->Indent();
264     for (int i = 0; i < map_fields.size(); ++i) {
265       const FieldDescriptor* field = map_fields[i];
266       const FieldGeneratorInfo* info =
267           context_->GetFieldGeneratorInfo(field);
268       printer->Print(
269         "case $number$:\n"
270         "  return internalGetMutable$capitalized_name$();\n",
271         "number", SimpleItoa(field->number()),
272         "capitalized_name", info->capitalized_name);
273     }
274     printer->Print(
275         "default:\n"
276         "  throw new RuntimeException(\n"
277         "      \"Invalid map field number: \" + number);\n");
278     printer->Outdent();
279     printer->Outdent();
280     printer->Print(
281         "  }\n"
282         "}\n");
283   }
284   printer->Print(
285     "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
286     "    internalGetFieldAccessorTable() {\n"
287     "  return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
288     "      .ensureFieldAccessorsInitialized(\n"
289     "          $classname$.class, $classname$.Builder.class);\n"
290     "}\n"
291     "\n",
292     "classname", name_resolver_->GetImmutableClassName(descriptor_),
293     "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
294     "identifier", UniqueFileScopeIdentifier(descriptor_),
295     "ver", GeneratedCodeVersionSuffix());
296 }
297 
298 // ===================================================================
299 
300 void MessageBuilderGenerator::
GenerateCommonBuilderMethods(io::Printer * printer)301 GenerateCommonBuilderMethods(io::Printer* printer) {
302   printer->Print(
303       "// Construct using $classname$.newBuilder()\n"
304       "private Builder() {\n"
305       "  maybeForceBuilderInitialization();\n"
306       "}\n"
307       "\n",
308       "classname", name_resolver_->GetImmutableClassName(descriptor_));
309 
310   printer->Print(
311     "private Builder(\n"
312     "    com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
313     "  super(parent);\n"
314     "  maybeForceBuilderInitialization();\n"
315     "}\n",
316     "classname", name_resolver_->GetImmutableClassName(descriptor_),
317     "ver", GeneratedCodeVersionSuffix());
318 
319   printer->Print(
320     "private void maybeForceBuilderInitialization() {\n"
321     "  if (com.google.protobuf.GeneratedMessage$ver$\n"
322     "          .alwaysUseFieldBuilders) {\n",
323     "ver", GeneratedCodeVersionSuffix());
324 
325   printer->Indent();
326   printer->Indent();
327   for (int i = 0; i < descriptor_->field_count(); i++) {
328     if (!descriptor_->field(i)->containing_oneof()) {
329       field_generators_.get(descriptor_->field(i))
330           .GenerateFieldBuilderInitializationCode(printer);
331     }
332   }
333   printer->Outdent();
334   printer->Outdent();
335 
336   printer->Print(
337     "  }\n"
338     "}\n");
339 
340   printer->Print(
341     "public Builder clear() {\n"
342     "  super.clear();\n");
343 
344   printer->Indent();
345 
346   for (int i = 0; i < descriptor_->field_count(); i++) {
347     if (!descriptor_->field(i)->containing_oneof()) {
348       field_generators_.get(descriptor_->field(i))
349           .GenerateBuilderClearCode(printer);
350     }
351   }
352 
353   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
354     printer->Print(
355       "$oneof_name$Case_ = 0;\n"
356       "$oneof_name$_ = null;\n",
357       "oneof_name", context_->GetOneofGeneratorInfo(
358           descriptor_->oneof_decl(i))->name);
359   }
360 
361   printer->Outdent();
362 
363   printer->Print(
364     "  return this;\n"
365     "}\n"
366     "\n");
367 
368   printer->Print(
369     "public com.google.protobuf.Descriptors.Descriptor\n"
370     "    getDescriptorForType() {\n"
371     "  return $fileclass$.internal_$identifier$_descriptor;\n"
372     "}\n"
373     "\n",
374     "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
375     "identifier", UniqueFileScopeIdentifier(descriptor_));
376 
377   // LITE runtime implements this in GeneratedMessageLite.
378   printer->Print(
379     "public $classname$ getDefaultInstanceForType() {\n"
380     "  return $classname$.getDefaultInstance();\n"
381     "}\n"
382     "\n",
383     "classname", name_resolver_->GetImmutableClassName(descriptor_));
384 
385   printer->Print(
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   printer->Print(
397     "public $classname$ buildPartial() {\n"
398     "  $classname$ result = new $classname$(this);\n",
399     "classname", name_resolver_->GetImmutableClassName(descriptor_));
400 
401   printer->Indent();
402 
403   int totalBuilderBits = 0;
404   int totalMessageBits = 0;
405   for (int i = 0; i < descriptor_->field_count(); i++) {
406     const ImmutableFieldGenerator& field =
407         field_generators_.get(descriptor_->field(i));
408     totalBuilderBits += field.GetNumBitsForBuilder();
409     totalMessageBits += field.GetNumBitsForMessage();
410   }
411   int totalBuilderInts = (totalBuilderBits + 31) / 32;
412   int totalMessageInts = (totalMessageBits + 31) / 32;
413 
414   if (GenerateHasBits(descriptor_)) {
415     // Local vars for from and to bit fields to avoid accessing the builder and
416     // message over and over for these fields. Seems to provide a slight
417     // perforamance improvement in micro benchmark and this is also what proto1
418     // code does.
419     for (int i = 0; i < totalBuilderInts; i++) {
420       printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
421         "bit_field_name", GetBitFieldName(i));
422     }
423     for (int i = 0; i < totalMessageInts; i++) {
424       printer->Print("int to_$bit_field_name$ = 0;\n",
425         "bit_field_name", GetBitFieldName(i));
426     }
427   }
428 
429   // Output generation code for each field.
430   for (int i = 0; i < descriptor_->field_count(); i++) {
431     field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
432   }
433 
434   if (GenerateHasBits(descriptor_)) {
435     // Copy the bit field results to the generated message
436     for (int i = 0; i < totalMessageInts; i++) {
437       printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
438         "bit_field_name", GetBitFieldName(i));
439     }
440   }
441 
442   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
443     printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
444                    "oneof_name", context_->GetOneofGeneratorInfo(
445                        descriptor_->oneof_decl(i))->name);
446   }
447 
448   printer->Outdent();
449 
450   printer->Print(
451     "  onBuilt();\n");
452 
453   printer->Print(
454     "  return result;\n"
455     "}\n"
456     "\n",
457     "classname", name_resolver_->GetImmutableClassName(descriptor_));
458 
459   printer->Print(
460     "public Builder clone() {\n"
461     "  return (Builder) super.clone();\n"
462     "}\n"
463     "public Builder setField(\n"
464     "    com.google.protobuf.Descriptors.FieldDescriptor field,\n"
465     "    Object value) {\n"
466     "  return (Builder) super.setField(field, value);\n"
467     "}\n"
468     "public Builder clearField(\n"
469     "    com.google.protobuf.Descriptors.FieldDescriptor field) {\n"
470     "  return (Builder) super.clearField(field);\n"
471     "}\n"
472     "public Builder clearOneof(\n"
473     "    com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n"
474     "  return (Builder) super.clearOneof(oneof);\n"
475     "}\n"
476     "public Builder setRepeatedField(\n"
477     "    com.google.protobuf.Descriptors.FieldDescriptor field,\n"
478     "    int index, Object value) {\n"
479     "  return (Builder) super.setRepeatedField(field, index, value);\n"
480     "}\n"
481     "public Builder addRepeatedField(\n"
482     "    com.google.protobuf.Descriptors.FieldDescriptor field,\n"
483     "    Object value) {\n"
484     "  return (Builder) super.addRepeatedField(field, value);\n"
485     "}\n");
486 
487   if (descriptor_->extension_range_count() > 0) {
488     printer->Print(
489       "public <Type> Builder setExtension(\n"
490       "    com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
491       "        $classname$, Type> extension,\n"
492       "    Type value) {\n"
493       "  return (Builder) super.setExtension(extension, value);\n"
494       "}\n"
495       "public <Type> Builder setExtension(\n"
496       "    com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
497       "        $classname$, java.util.List<Type>> extension,\n"
498       "    int index, Type value) {\n"
499       "  return (Builder) super.setExtension(extension, index, value);\n"
500       "}\n"
501       "public <Type> Builder addExtension(\n"
502       "    com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
503       "        $classname$, java.util.List<Type>> extension,\n"
504       "    Type value) {\n"
505       "  return (Builder) super.addExtension(extension, value);\n"
506       "}\n"
507       "public <Type> Builder clearExtension(\n"
508       "    com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
509       "        $classname$, ?> extension) {\n"
510       "  return (Builder) super.clearExtension(extension);\n"
511       "}\n",
512       "classname", name_resolver_->GetImmutableClassName(descriptor_));
513   }
514 
515   // -----------------------------------------------------------------
516 
517   if (context_->HasGeneratedMethods(descriptor_)) {
518     printer->Print(
519       "public Builder mergeFrom(com.google.protobuf.Message other) {\n"
520       "  if (other instanceof $classname$) {\n"
521       "    return mergeFrom(($classname$)other);\n"
522       "  } else {\n"
523       "    super.mergeFrom(other);\n"
524       "    return this;\n"
525       "  }\n"
526       "}\n"
527       "\n",
528       "classname", name_resolver_->GetImmutableClassName(descriptor_));
529 
530     printer->Print(
531       "public Builder mergeFrom($classname$ other) {\n"
532       // Optimization:  If other is the default instance, we know none of its
533       //   fields are set so we can skip the merge.
534       "  if (other == $classname$.getDefaultInstance()) return this;\n",
535       "classname", name_resolver_->GetImmutableClassName(descriptor_));
536     printer->Indent();
537 
538     for (int i = 0; i < descriptor_->field_count(); i++) {
539       if (!descriptor_->field(i)->containing_oneof()) {
540         field_generators_.get(
541             descriptor_->field(i)).GenerateMergingCode(printer);
542       }
543     }
544 
545     // Merge oneof fields.
546     for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
547       printer->Print(
548         "switch (other.get$oneof_capitalized_name$Case()) {\n",
549         "oneof_capitalized_name",
550         context_->GetOneofGeneratorInfo(
551             descriptor_->oneof_decl(i))->capitalized_name);
552       printer->Indent();
553       for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
554         const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
555         printer->Print(
556           "case $field_name$: {\n",
557           "field_name",
558           ToUpper(field->name()));
559         printer->Indent();
560         field_generators_.get(field).GenerateMergingCode(printer);
561         printer->Print(
562             "break;\n");
563         printer->Outdent();
564         printer->Print(
565             "}\n");
566       }
567       printer->Print(
568         "case $cap_oneof_name$_NOT_SET: {\n"
569         "  break;\n"
570         "}\n",
571         "cap_oneof_name",
572         ToUpper(context_->GetOneofGeneratorInfo(
573             descriptor_->oneof_decl(i))->name));
574       printer->Outdent();
575       printer->Print(
576           "}\n");
577     }
578 
579     printer->Outdent();
580 
581     // if message type has extensions
582     if (descriptor_->extension_range_count() > 0) {
583       printer->Print(
584         "  this.mergeExtensionFields(other);\n");
585     }
586 
587     if (PreserveUnknownFields(descriptor_)) {
588       printer->Print(
589         "  this.mergeUnknownFields(other.unknownFields);\n");
590     }
591 
592     printer->Print(
593       "  onChanged();\n");
594 
595     printer->Print(
596       "  return this;\n"
597       "}\n"
598       "\n");
599 
600   }
601 }
602 
603 // ===================================================================
604 
605 void MessageBuilderGenerator::
GenerateBuilderParsingMethods(io::Printer * printer)606 GenerateBuilderParsingMethods(io::Printer* printer) {
607   printer->Print(
608     "public Builder mergeFrom(\n"
609     "    com.google.protobuf.CodedInputStream input,\n"
610     "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
611     "    throws java.io.IOException {\n"
612     "  $classname$ parsedMessage = null;\n"
613     "  try {\n"
614     "    parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
615     "  } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
616     "    parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
617     "    throw e.unwrapIOException();\n"
618     "  } finally {\n"
619     "    if (parsedMessage != null) {\n"
620     "      mergeFrom(parsedMessage);\n"
621     "    }\n"
622     "  }\n"
623     "  return this;\n"
624     "}\n",
625     "classname", name_resolver_->GetImmutableClassName(descriptor_));
626 }
627 
628 // ===================================================================
629 
GenerateIsInitialized(io::Printer * printer)630 void MessageBuilderGenerator::GenerateIsInitialized(
631     io::Printer* printer) {
632   printer->Print(
633     "public final boolean isInitialized() {\n");
634   printer->Indent();
635 
636   // Check that all required fields in this message are set.
637   // TODO(kenton):  We can optimize this when we switch to putting all the
638   //   "has" fields into a single bitfield.
639   for (int i = 0; i < descriptor_->field_count(); i++) {
640     const FieldDescriptor* field = descriptor_->field(i);
641     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
642 
643     if (field->is_required()) {
644       printer->Print(
645         "if (!has$name$()) {\n"
646         "  return false;\n"
647         "}\n",
648         "name", info->capitalized_name);
649     }
650   }
651 
652   // Now check that all embedded messages are initialized.
653   for (int i = 0; i < descriptor_->field_count(); i++) {
654     const FieldDescriptor* field = descriptor_->field(i);
655     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
656     if (GetJavaType(field) == JAVATYPE_MESSAGE &&
657         HasRequiredFields(field->message_type())) {
658       switch (field->label()) {
659         case FieldDescriptor::LABEL_REQUIRED:
660           printer->Print(
661             "if (!get$name$().isInitialized()) {\n"
662              "  return false;\n"
663              "}\n",
664             "type", name_resolver_->GetImmutableClassName(
665                 field->message_type()),
666             "name", info->capitalized_name);
667           break;
668         case FieldDescriptor::LABEL_OPTIONAL:
669           if (!SupportFieldPresence(descriptor_->file()) &&
670               field->containing_oneof() != NULL) {
671             const OneofDescriptor* oneof = field->containing_oneof();
672             const OneofGeneratorInfo* oneof_info =
673                 context_->GetOneofGeneratorInfo(oneof);
674             printer->Print(
675               "if ($oneof_name$Case_ == $field_number$) {\n",
676               "oneof_name", oneof_info->name,
677               "field_number", SimpleItoa(field->number()));
678           } else {
679             printer->Print(
680               "if (has$name$()) {\n",
681               "name", info->capitalized_name);
682           }
683           printer->Print(
684             "  if (!get$name$().isInitialized()) {\n"
685             "    return false;\n"
686             "  }\n"
687             "}\n",
688             "name", info->capitalized_name);
689           break;
690         case FieldDescriptor::LABEL_REPEATED:
691           if (IsMapEntry(field->message_type())) {
692             printer->Print(
693               "for ($type$ item : get$name$().values()) {\n"
694               "  if (!item.isInitialized()) {\n"
695               "    return false;\n"
696               "  }\n"
697               "}\n",
698               "type", MapValueImmutableClassdName(field->message_type(),
699                                                   name_resolver_),
700               "name", info->capitalized_name);
701           } else {
702             printer->Print(
703               "for (int i = 0; i < get$name$Count(); i++) {\n"
704               "  if (!get$name$(i).isInitialized()) {\n"
705               "    return false;\n"
706               "  }\n"
707               "}\n",
708               "type", name_resolver_->GetImmutableClassName(
709                   field->message_type()),
710               "name", info->capitalized_name);
711           }
712           break;
713       }
714     }
715   }
716 
717   if (descriptor_->extension_range_count() > 0) {
718     printer->Print(
719       "if (!extensionsAreInitialized()) {\n"
720       "  return false;\n"
721       "}\n");
722   }
723 
724   printer->Outdent();
725 
726   printer->Print(
727     "  return true;\n"
728     "}\n"
729     "\n");
730 }
731 
732 // ===================================================================
733 
734 }  // namespace java
735 }  // namespace compiler
736 }  // namespace protobuf
737 }  // namespace google
738