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 <google/protobuf/compiler/java/java_message.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_message_builder.h>
53 #include <google/protobuf/compiler/java/java_message_builder_lite.h>
54 #include <google/protobuf/compiler/java/java_name_resolver.h>
55 #include <google/protobuf/io/coded_stream.h>
56 #include <google/protobuf/io/printer.h>
57 #include <google/protobuf/descriptor.pb.h>
58 #include <google/protobuf/wire_format.h>
59 #include <google/protobuf/stubs/strutil.h>
60 #include <google/protobuf/stubs/substitute.h>
61 
62 namespace google {
63 namespace protobuf {
64 namespace compiler {
65 namespace java {
66 
67 using internal::WireFormat;
68 using internal::WireFormatLite;
69 
70 namespace {
GenerateHasBits(const Descriptor * descriptor)71 bool GenerateHasBits(const Descriptor* descriptor) {
72   return SupportFieldPresence(descriptor->file()) ||
73       HasRepeatedFields(descriptor);
74 }
75 
MapValueImmutableClassdName(const Descriptor * descriptor,ClassNameResolver * name_resolver)76 string MapValueImmutableClassdName(const Descriptor* descriptor,
77                                    ClassNameResolver* name_resolver) {
78   const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
79   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
80   return name_resolver->GetImmutableClassName(value_field->message_type());
81 }
82 }  // namespace
83 
84 // ===================================================================
85 
MessageGenerator(const Descriptor * descriptor)86 MessageGenerator::MessageGenerator(const Descriptor* descriptor)
87   : descriptor_(descriptor) {}
88 
~MessageGenerator()89 MessageGenerator::~MessageGenerator() {}
90 
91 // ===================================================================
ImmutableMessageGenerator(const Descriptor * descriptor,Context * context)92 ImmutableMessageGenerator::ImmutableMessageGenerator(
93     const Descriptor* descriptor, Context* context)
94   : MessageGenerator(descriptor), context_(context),
95     name_resolver_(context->GetNameResolver()),
96     field_generators_(descriptor, context_) {
97   GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
98       << "Generator factory error: A non-lite message generator is used to "
99          "generate lite messages.";
100 }
101 
~ImmutableMessageGenerator()102 ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
103 
GenerateStaticVariables(io::Printer * printer,int * bytecode_estimate)104 void ImmutableMessageGenerator::GenerateStaticVariables(
105     io::Printer* printer, int* bytecode_estimate) {
106   // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
107   // used in the construction of descriptors, we have a tricky bootstrapping
108   // problem.  To help control static initialization order, we make sure all
109   // descriptors and other static data that depends on them are members of
110   // the outermost class in the file.  This way, they will be initialized in
111   // a deterministic order.
112 
113   map<string, string> vars;
114   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
115   vars["index"] = SimpleItoa(descriptor_->index());
116   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
117   if (descriptor_->containing_type() != NULL) {
118     vars["parent"] = UniqueFileScopeIdentifier(
119         descriptor_->containing_type());
120   }
121   if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
122     // We can only make these package-private since the classes that use them
123     // are in separate files.
124     vars["private"] = "";
125   } else {
126     vars["private"] = "private ";
127   }
128   if (*bytecode_estimate <= kMaxStaticSize) {
129     vars["final"] = "final ";
130   } else {
131     vars["final"] = "";
132   }
133 
134   // The descriptor for this type.
135   printer->Print(vars,
136     // TODO(teboring): final needs to be added back. The way to fix it is to
137     // generate methods that can construct the types, and then still declare the
138     // types, and then init them in clinit with the new method calls.
139     "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n"
140     "  internal_$identifier$_descriptor;\n");
141   *bytecode_estimate += 30;
142 
143   // And the FieldAccessorTable.
144   GenerateFieldAccessorTable(printer, bytecode_estimate);
145 
146   // Generate static members for all nested types.
147   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
148     // TODO(kenton):  Reuse MessageGenerator objects?
149     ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
150         .GenerateStaticVariables(printer, bytecode_estimate);
151   }
152 }
153 
GenerateStaticVariableInitializers(io::Printer * printer)154 int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
155     io::Printer* printer) {
156   int bytecode_estimate = 0;
157   map<string, string> vars;
158   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
159   vars["index"] = SimpleItoa(descriptor_->index());
160   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
161   if (descriptor_->containing_type() != NULL) {
162     vars["parent"] = UniqueFileScopeIdentifier(
163         descriptor_->containing_type());
164   }
165 
166   // The descriptor for this type.
167   if (descriptor_->containing_type() == NULL) {
168     printer->Print(vars,
169       "internal_$identifier$_descriptor =\n"
170       "  getDescriptor().getMessageTypes().get($index$);\n");
171     bytecode_estimate += 30;
172   } else {
173     printer->Print(vars,
174       "internal_$identifier$_descriptor =\n"
175       "  internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
176     bytecode_estimate += 30;
177   }
178 
179   // And the FieldAccessorTable.
180   bytecode_estimate += GenerateFieldAccessorTableInitializer(printer);
181 
182   // Generate static member initializers for all nested types.
183   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
184     // TODO(kenton):  Reuse MessageGenerator objects?
185     bytecode_estimate +=
186         ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
187             .GenerateStaticVariableInitializers(printer);
188   }
189   return bytecode_estimate;
190 }
191 
192 void ImmutableMessageGenerator::
GenerateFieldAccessorTable(io::Printer * printer,int * bytecode_estimate)193 GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate) {
194   map<string, string> vars;
195   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
196   if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
197     // We can only make these package-private since the classes that use them
198     // are in separate files.
199     vars["private"] = "";
200   } else {
201     vars["private"] = "private ";
202   }
203   if (*bytecode_estimate <= kMaxStaticSize) {
204     vars["final"] = "final ";
205   } else {
206     vars["final"] = "";
207   }
208   vars["ver"] = GeneratedCodeVersionSuffix();
209   printer->Print(vars,
210     "$private$static $final$\n"
211     "  com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
212     "    internal_$identifier$_fieldAccessorTable;\n");
213 
214   // 6 bytes per field and oneof
215   *bytecode_estimate += 10 + 6 * descriptor_->field_count()
216       + 6 * descriptor_->oneof_decl_count();
217 }
218 
219 int ImmutableMessageGenerator::
GenerateFieldAccessorTableInitializer(io::Printer * printer)220 GenerateFieldAccessorTableInitializer(io::Printer* printer) {
221   int bytecode_estimate = 10;
222   printer->Print(
223     "internal_$identifier$_fieldAccessorTable = new\n"
224     "  com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n"
225     "    internal_$identifier$_descriptor,\n"
226     "    new java.lang.String[] { ",
227     "identifier", UniqueFileScopeIdentifier(descriptor_),
228     "ver", GeneratedCodeVersionSuffix());
229   for (int i = 0; i < descriptor_->field_count(); i++) {
230     const FieldDescriptor* field = descriptor_->field(i);
231     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
232     bytecode_estimate += 6;
233     printer->Print(
234       "\"$field_name$\", ",
235       "field_name", info->capitalized_name);
236   }
237   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
238     const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
239     const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
240     bytecode_estimate += 6;
241     printer->Print(
242       "\"$oneof_name$\", ",
243       "oneof_name", info->capitalized_name);
244   }
245   printer->Print("});\n");
246   return bytecode_estimate;
247 }
248 
249 // ===================================================================
250 
GenerateInterface(io::Printer * printer)251 void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
252   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
253                                 /* immutable = */ true, "OrBuilder");
254   if (descriptor_->extension_range_count() > 0) {
255     printer->Print(
256         "public interface $classname$OrBuilder$idend$ extends\n"
257         "    $extra_interfaces$\n"
258         "    com.google.protobuf.GeneratedMessage$ver$.\n"
259         "        ExtendableMessageOrBuilder<$classname$> {\n",
260         "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
261         "classname", descriptor_->name(),
262         "idend", "", "ver", GeneratedCodeVersionSuffix());
263   } else {
264     printer->Print(
265         "public interface $classname$OrBuilder$idend$ extends\n"
266         "    $extra_interfaces$\n"
267         "    com.google.protobuf.MessageOrBuilder {\n",
268         "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
269         "classname", descriptor_->name(),
270         "idend", "");
271   }
272   printer->Annotate("classname", "idend", descriptor_);
273 
274   printer->Indent();
275     for (int i = 0; i < descriptor_->field_count(); i++) {
276       printer->Print("\n");
277       field_generators_.get(descriptor_->field(i))
278                        .GenerateInterfaceMembers(printer);
279     }
280     for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
281       printer->Print(
282           "\n"
283           "public $classname$.$oneof_capitalized_name$Case "
284           "get$oneof_capitalized_name$Case();\n",
285           "oneof_capitalized_name",
286           context_->GetOneofGeneratorInfo(
287               descriptor_->oneof_decl(i))->capitalized_name,
288           "classname",
289           context_->GetNameResolver()->GetImmutableClassName(
290               descriptor_));
291     }
292   printer->Outdent();
293 
294   printer->Print("}\n");
295 }
296 
297 // ===================================================================
298 
Generate(io::Printer * printer)299 void ImmutableMessageGenerator::Generate(io::Printer* printer) {
300   bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
301 
302   map<string, string> variables;
303   variables["static"] = is_own_file ? " " : " static ";
304   variables["classname"] = descriptor_->name();
305   variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
306   variables["ver"] = GeneratedCodeVersionSuffix();
307 
308   WriteMessageDocComment(printer, descriptor_);
309   MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
310                                 /* immutable = */ true);
311 
312   // The builder_type stores the super type name of the nested Builder class.
313   string builder_type;
314   if (descriptor_->extension_range_count() > 0) {
315     printer->Print(variables,
316                    "public $static$final class $classname$ extends\n");
317     printer->Annotate("classname", descriptor_);
318     printer->Print(
319         variables,
320         "    com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n"
321         "      $classname$> implements\n"
322         "    $extra_interfaces$\n"
323         "    $classname$OrBuilder {\n");
324     builder_type = strings::Substitute(
325         "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
326         name_resolver_->GetImmutableClassName(descriptor_),
327         GeneratedCodeVersionSuffix());
328   } else {
329     printer->Print(variables,
330                    "public $static$final class $classname$ extends\n");
331     printer->Annotate("classname", descriptor_);
332     printer->Print(variables,
333       "    com.google.protobuf.GeneratedMessage$ver$ implements\n"
334       "    $extra_interfaces$\n"
335       "    $classname$OrBuilder {\n");
336     builder_type = strings::Substitute(
337         "com.google.protobuf.GeneratedMessage$0.Builder<?>",
338         GeneratedCodeVersionSuffix());
339   }
340   printer->Indent();
341   // Using builder_type, instead of Builder, prevents the Builder class from
342   // being loaded into PermGen space when the default instance is created.
343   // This optimizes the PermGen space usage for clients that do not modify
344   // messages.
345   printer->Print(
346     "// Use $classname$.newBuilder() to construct.\n"
347     "private $classname$($buildertype$ builder) {\n"
348     "  super(builder);\n"
349     "}\n",
350     "classname", descriptor_->name(),
351     "buildertype", builder_type);
352   printer->Print(
353     "private $classname$() {\n",
354     "classname", descriptor_->name());
355   printer->Indent();
356   GenerateInitializers(printer);
357   printer->Outdent();
358   printer->Print(
359     "}\n"
360     "\n");
361 
362   printer->Print(
363     "@java.lang.Override\n"
364     "public final com.google.protobuf.UnknownFieldSet\n"
365     "getUnknownFields() {\n");
366   if (PreserveUnknownFields(descriptor_)) {
367     printer->Print(
368       "  return this.unknownFields;\n");
369   } else {
370     printer->Print(
371       "  return com.google.protobuf.UnknownFieldSet.getDefaultInstance();\n");
372   }
373   printer->Print(
374     "}\n");
375 
376   if (context_->HasGeneratedMethods(descriptor_)) {
377     GenerateParsingConstructor(printer);
378   }
379 
380   GenerateDescriptorMethods(printer);
381 
382   // Nested types
383   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
384     EnumGenerator(descriptor_->enum_type(i), true, context_)
385         .Generate(printer);
386   }
387 
388   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
389     // Don't generate Java classes for map entry messages.
390     if (IsMapEntry(descriptor_->nested_type(i))) continue;
391     ImmutableMessageGenerator messageGenerator(
392         descriptor_->nested_type(i), context_);
393     messageGenerator.GenerateInterface(printer);
394     messageGenerator.Generate(printer);
395   }
396 
397   if (GenerateHasBits(descriptor_)) {
398     // Integers for bit fields.
399     int totalBits = 0;
400     for (int i = 0; i < descriptor_->field_count(); i++) {
401       totalBits += field_generators_.get(descriptor_->field(i))
402           .GetNumBitsForMessage();
403     }
404     int totalInts = (totalBits + 31) / 32;
405     for (int i = 0; i < totalInts; i++) {
406       printer->Print("private int $bit_field_name$;\n",
407         "bit_field_name", GetBitFieldName(i));
408     }
409   }
410 
411   // oneof
412   map<string, string> vars;
413   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
414     vars["oneof_name"] = context_->GetOneofGeneratorInfo(
415         descriptor_->oneof_decl(i))->name;
416     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
417         descriptor_->oneof_decl(i))->capitalized_name;
418     vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
419     // oneofCase_ and oneof_
420     printer->Print(vars,
421       "private int $oneof_name$Case_ = 0;\n"
422       "private java.lang.Object $oneof_name$_;\n");
423     // OneofCase enum
424     printer->Print(vars,
425       "public enum $oneof_capitalized_name$Case\n"
426       "    implements com.google.protobuf.Internal.EnumLite {\n");
427     printer->Indent();
428     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
429       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
430       printer->Print(
431         "$field_name$($field_number$),\n",
432         "field_name",
433         ToUpper(field->name()),
434         "field_number",
435         SimpleItoa(field->number()));
436     }
437     printer->Print(
438       "$cap_oneof_name$_NOT_SET(0);\n",
439       "cap_oneof_name",
440       ToUpper(vars["oneof_name"]));
441     printer->Print(vars,
442       "private final int value;\n"
443       "private $oneof_capitalized_name$Case(int value) {\n"
444       "  this.value = value;\n"
445       "}\n");
446     printer->Print(vars,
447       "/**\n"
448       " * @deprecated Use {@link #forNumber(int)} instead.\n"
449       " */\n"
450       "@java.lang.Deprecated\n"
451       "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
452       "  return forNumber(value);\n"
453       "}\n"
454       "\n"
455       "public static $oneof_capitalized_name$Case forNumber(int value) {\n"
456       "  switch (value) {\n");
457     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
458       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
459       printer->Print(
460         "    case $field_number$: return $field_name$;\n",
461         "field_number",
462         SimpleItoa(field->number()),
463         "field_name",
464         ToUpper(field->name()));
465     }
466     printer->Print(
467       "    case 0: return $cap_oneof_name$_NOT_SET;\n"
468       "    default: return null;\n"
469       "  }\n"
470       "}\n"
471       "public int getNumber() {\n"
472       "  return this.value;\n"
473       "}\n",
474       "cap_oneof_name", ToUpper(vars["oneof_name"]));
475     printer->Outdent();
476     printer->Print("};\n\n");
477     // oneofCase()
478     printer->Print(vars,
479       "public $oneof_capitalized_name$Case\n"
480       "get$oneof_capitalized_name$Case() {\n"
481       "  return $oneof_capitalized_name$Case.forNumber(\n"
482       "      $oneof_name$Case_);\n"
483       "}\n"
484       "\n");
485   }
486 
487   if (IsAnyMessage(descriptor_)) {
488     GenerateAnyMethods(printer);
489   }
490 
491   // Fields
492   for (int i = 0; i < descriptor_->field_count(); i++) {
493     printer->Print("public static final int $constant_name$ = $number$;\n",
494       "constant_name", FieldConstantName(descriptor_->field(i)),
495       "number", SimpleItoa(descriptor_->field(i)->number()));
496     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
497     printer->Print("\n");
498   }
499 
500   if (context_->HasGeneratedMethods(descriptor_)) {
501     GenerateIsInitialized(printer);
502     GenerateMessageSerializationMethods(printer);
503     GenerateEqualsAndHashCode(printer);
504   }
505 
506 
507   GenerateParseFromMethods(printer);
508   GenerateBuilder(printer);
509 
510   printer->Print(
511     "\n"
512     "// @@protoc_insertion_point(class_scope:$full_name$)\n",
513     "full_name", descriptor_->full_name());
514 
515 
516   // Carefully initialize the default instance in such a way that it doesn't
517   // conflict with other initialization.
518   printer->Print(
519     "private static final $classname$ DEFAULT_INSTANCE;\n",
520     "classname", name_resolver_->GetImmutableClassName(descriptor_));
521   printer->Print(
522     "static {\n"
523     "  DEFAULT_INSTANCE = new $classname$();\n"
524     "}\n"
525     "\n",
526     "classname", name_resolver_->GetImmutableClassName(descriptor_));
527 
528   printer->Print(
529       "public static $classname$ getDefaultInstance() {\n"
530       "  return DEFAULT_INSTANCE;\n"
531       "}\n"
532       "\n",
533       "classname", name_resolver_->GetImmutableClassName(descriptor_));
534 
535   GenerateParser(printer);
536 
537   printer->Print(
538     "public $classname$ getDefaultInstanceForType() {\n"
539     "  return DEFAULT_INSTANCE;\n"
540     "}\n"
541     "\n",
542     "classname", name_resolver_->GetImmutableClassName(descriptor_));
543 
544   // Extensions must be declared after the DEFAULT_INSTANCE is initialized
545   // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
546   // the outer class's FileDescriptor.
547   for (int i = 0; i < descriptor_->extension_count(); i++) {
548     ImmutableExtensionGenerator(descriptor_->extension(i), context_)
549         .Generate(printer);
550   }
551 
552   printer->Outdent();
553   printer->Print("}\n\n");
554 }
555 
556 
557 // ===================================================================
558 
559 void ImmutableMessageGenerator::
GenerateMessageSerializationMethods(io::Printer * printer)560 GenerateMessageSerializationMethods(io::Printer* printer) {
561   google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
562       SortFieldsByNumber(descriptor_));
563 
564   vector<const Descriptor::ExtensionRange*> sorted_extensions;
565   for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
566     sorted_extensions.push_back(descriptor_->extension_range(i));
567   }
568   std::sort(sorted_extensions.begin(), sorted_extensions.end(),
569             ExtensionRangeOrdering());
570 
571   printer->Print(
572     "public void writeTo(com.google.protobuf.CodedOutputStream output)\n"
573     "                    throws java.io.IOException {\n");
574   printer->Indent();
575   if (HasPackedFields(descriptor_)) {
576     // writeTo(CodedOutputStream output) might be invoked without
577     // getSerializedSize() ever being called, but we need the memoized
578     // sizes in case this message has packed fields. Rather than emit checks for
579     // each packed field, just call getSerializedSize() up front.
580     // In most cases, getSerializedSize() will have already been called anyway
581     // by one of the wrapper writeTo() methods, making this call cheap.
582     printer->Print(
583       "getSerializedSize();\n");
584   }
585 
586   if (descriptor_->extension_range_count() > 0) {
587     if (descriptor_->options().message_set_wire_format()) {
588       printer->Print(
589         "com.google.protobuf.GeneratedMessage$ver$\n"
590         "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
591         "    extensionWriter = newMessageSetExtensionWriter();\n",
592         "classname", name_resolver_->GetImmutableClassName(descriptor_),
593         "ver", GeneratedCodeVersionSuffix());
594     } else {
595       printer->Print(
596         "com.google.protobuf.GeneratedMessage$ver$\n"
597         "  .ExtendableMessage<$classname$>.ExtensionWriter\n"
598         "    extensionWriter = newExtensionWriter();\n",
599         "classname", name_resolver_->GetImmutableClassName(descriptor_),
600         "ver", GeneratedCodeVersionSuffix());
601     }
602   }
603 
604   // Merge the fields and the extension ranges, both sorted by field number.
605   for (int i = 0, j = 0;
606        i < descriptor_->field_count() || j < sorted_extensions.size();
607        ) {
608     if (i == descriptor_->field_count()) {
609       GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
610     } else if (j == sorted_extensions.size()) {
611       GenerateSerializeOneField(printer, sorted_fields[i++]);
612     } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
613       GenerateSerializeOneField(printer, sorted_fields[i++]);
614     } else {
615       GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
616     }
617   }
618 
619   if (PreserveUnknownFields(descriptor_)) {
620     if (descriptor_->options().message_set_wire_format()) {
621       printer->Print(
622         "unknownFields.writeAsMessageSetTo(output);\n");
623     } else {
624       printer->Print(
625         "unknownFields.writeTo(output);\n");
626     }
627   }
628 
629   printer->Outdent();
630   printer->Print(
631     "}\n"
632     "\n"
633     "public int getSerializedSize() {\n"
634     "  int size = memoizedSize;\n"
635     "  if (size != -1) return size;\n"
636     "\n"
637     "  size = 0;\n");
638   printer->Indent();
639 
640   for (int i = 0; i < descriptor_->field_count(); i++) {
641     field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
642   }
643 
644   if (descriptor_->extension_range_count() > 0) {
645     if (descriptor_->options().message_set_wire_format()) {
646       printer->Print(
647         "size += extensionsSerializedSizeAsMessageSet();\n");
648     } else {
649       printer->Print(
650         "size += extensionsSerializedSize();\n");
651     }
652   }
653 
654   if (PreserveUnknownFields(descriptor_)) {
655     if (descriptor_->options().message_set_wire_format()) {
656       printer->Print(
657         "size += unknownFields.getSerializedSizeAsMessageSet();\n");
658     } else {
659       printer->Print(
660         "size += unknownFields.getSerializedSize();\n");
661     }
662   }
663 
664   printer->Outdent();
665   printer->Print(
666     "  memoizedSize = size;\n"
667     "  return size;\n"
668     "}\n"
669     "\n");
670 
671   printer->Print(
672     "private static final long serialVersionUID = 0L;\n");
673 }
674 
675 void ImmutableMessageGenerator::
GenerateParseFromMethods(io::Printer * printer)676 GenerateParseFromMethods(io::Printer* printer) {
677   // Note:  These are separate from GenerateMessageSerializationMethods()
678   //   because they need to be generated even for messages that are optimized
679   //   for code size.
680   printer->Print(
681     "public static $classname$ parseFrom(\n"
682     "    com.google.protobuf.ByteString data)\n"
683     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
684     "  return PARSER.parseFrom(data);\n"
685     "}\n"
686     "public static $classname$ parseFrom(\n"
687     "    com.google.protobuf.ByteString data,\n"
688     "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
689     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
690     "  return PARSER.parseFrom(data, extensionRegistry);\n"
691     "}\n"
692     "public static $classname$ parseFrom(byte[] data)\n"
693     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
694     "  return PARSER.parseFrom(data);\n"
695     "}\n"
696     "public static $classname$ parseFrom(\n"
697     "    byte[] data,\n"
698     "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
699     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
700     "  return PARSER.parseFrom(data, extensionRegistry);\n"
701     "}\n"
702     "public static $classname$ parseFrom(java.io.InputStream input)\n"
703     "    throws java.io.IOException {\n"
704     "  return com.google.protobuf.GeneratedMessage$ver$\n"
705     "      .parseWithIOException(PARSER, input);\n"
706     "}\n"
707     "public static $classname$ parseFrom(\n"
708     "    java.io.InputStream input,\n"
709     "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
710     "    throws java.io.IOException {\n"
711     "  return com.google.protobuf.GeneratedMessage$ver$\n"
712     "      .parseWithIOException(PARSER, input, extensionRegistry);\n"
713     "}\n"
714     "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
715     "    throws java.io.IOException {\n"
716     "  return com.google.protobuf.GeneratedMessage$ver$\n"
717     "      .parseDelimitedWithIOException(PARSER, input);\n"
718     "}\n"
719     "public static $classname$ parseDelimitedFrom(\n"
720     "    java.io.InputStream input,\n"
721     "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
722     "    throws java.io.IOException {\n"
723     "  return com.google.protobuf.GeneratedMessage$ver$\n"
724     "      .parseDelimitedWithIOException(PARSER, input, extensionRegistry);\n"
725     "}\n"
726     "public static $classname$ parseFrom(\n"
727     "    com.google.protobuf.CodedInputStream input)\n"
728     "    throws java.io.IOException {\n"
729     "  return com.google.protobuf.GeneratedMessage$ver$\n"
730     "      .parseWithIOException(PARSER, input);\n"
731     "}\n"
732     "public static $classname$ parseFrom(\n"
733     "    com.google.protobuf.CodedInputStream input,\n"
734     "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
735     "    throws java.io.IOException {\n"
736     "  return com.google.protobuf.GeneratedMessage$ver$\n"
737     "      .parseWithIOException(PARSER, input, extensionRegistry);\n"
738     "}\n"
739     "\n",
740     "classname", name_resolver_->GetImmutableClassName(descriptor_),
741     "ver", GeneratedCodeVersionSuffix());
742 }
743 
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)744 void ImmutableMessageGenerator::GenerateSerializeOneField(
745     io::Printer* printer, const FieldDescriptor* field) {
746   field_generators_.get(field).GenerateSerializationCode(printer);
747 }
748 
GenerateSerializeOneExtensionRange(io::Printer * printer,const Descriptor::ExtensionRange * range)749 void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
750     io::Printer* printer, const Descriptor::ExtensionRange* range) {
751   printer->Print(
752     "extensionWriter.writeUntil($end$, output);\n",
753     "end", SimpleItoa(range->end));
754 }
755 
756 // ===================================================================
757 
GenerateBuilder(io::Printer * printer)758 void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
759   // LITE_RUNTIME implements this at the GeneratedMessageLite level.
760   printer->Print(
761     "public Builder newBuilderForType() { return newBuilder(); }\n");
762 
763   printer->Print(
764     "public static Builder newBuilder() {\n"
765     "  return DEFAULT_INSTANCE.toBuilder();\n"
766     "}\n"
767     "public static Builder newBuilder($classname$ prototype) {\n"
768     "  return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n"
769     "}\n"
770     "public Builder toBuilder() {\n"
771     "  return this == DEFAULT_INSTANCE\n"
772     "      ? new Builder() : new Builder().mergeFrom(this);\n"
773     "}\n"
774     "\n",
775     "classname", name_resolver_->GetImmutableClassName(descriptor_));
776 
777   printer->Print(
778     "@java.lang.Override\n"
779     "protected Builder newBuilderForType(\n"
780     "    com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
781     "  Builder builder = new Builder(parent);\n"
782     "  return builder;\n"
783     "}\n",
784     "ver", GeneratedCodeVersionSuffix());
785 
786   MessageBuilderGenerator builderGenerator(descriptor_, context_);
787   builderGenerator.Generate(printer);
788 }
789 
790 void ImmutableMessageGenerator::
GenerateDescriptorMethods(io::Printer * printer)791 GenerateDescriptorMethods(io::Printer* printer) {
792   if (!descriptor_->options().no_standard_descriptor_accessor()) {
793     printer->Print(
794       "public static final com.google.protobuf.Descriptors.Descriptor\n"
795       "    getDescriptor() {\n"
796       "  return $fileclass$.internal_$identifier$_descriptor;\n"
797       "}\n"
798       "\n",
799       "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
800       "identifier", UniqueFileScopeIdentifier(descriptor_));
801   }
802   vector<const FieldDescriptor*> map_fields;
803   for (int i = 0; i < descriptor_->field_count(); i++) {
804     const FieldDescriptor* field = descriptor_->field(i);
805     if (GetJavaType(field) == JAVATYPE_MESSAGE &&
806         IsMapEntry(field->message_type())) {
807       map_fields.push_back(field);
808     }
809   }
810   if (!map_fields.empty()) {
811     printer->Print(
812       "@SuppressWarnings({\"rawtypes\"})\n"
813       "protected com.google.protobuf.MapField internalGetMapField(\n"
814       "    int number) {\n"
815       "  switch (number) {\n");
816     printer->Indent();
817     printer->Indent();
818     for (int i = 0; i < map_fields.size(); ++i) {
819       const FieldDescriptor* field = map_fields[i];
820       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
821       printer->Print(
822         "case $number$:\n"
823         "  return internalGet$capitalized_name$();\n",
824         "number", SimpleItoa(field->number()),
825         "capitalized_name", info->capitalized_name);
826     }
827     printer->Print(
828         "default:\n"
829         "  throw new RuntimeException(\n"
830         "      \"Invalid map field number: \" + number);\n");
831     printer->Outdent();
832     printer->Outdent();
833     printer->Print(
834         "  }\n"
835         "}\n");
836   }
837   printer->Print(
838     "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
839     "    internalGetFieldAccessorTable() {\n"
840     "  return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
841     "      .ensureFieldAccessorsInitialized(\n"
842     "          $classname$.class, $classname$.Builder.class);\n"
843     "}\n"
844     "\n",
845     "classname", name_resolver_->GetImmutableClassName(descriptor_),
846     "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
847     "identifier", UniqueFileScopeIdentifier(descriptor_),
848     "ver", GeneratedCodeVersionSuffix());
849 }
850 
851 // ===================================================================
852 
GenerateIsInitialized(io::Printer * printer)853 void ImmutableMessageGenerator::GenerateIsInitialized(
854     io::Printer* printer) {
855   // Memoizes whether the protocol buffer is fully initialized (has all
856   // required fields). -1 means not yet computed. 0 means false and 1 means
857   // true.
858   printer->Print(
859     "private byte memoizedIsInitialized = -1;\n");
860   printer->Print(
861     "public final boolean isInitialized() {\n");
862   printer->Indent();
863 
864   // Don't directly compare to -1 to avoid an Android x86 JIT bug.
865   printer->Print(
866     "byte isInitialized = memoizedIsInitialized;\n"
867     "if (isInitialized == 1) return true;\n"
868     "if (isInitialized == 0) return false;\n"
869     "\n");
870 
871   // Check that all required fields in this message are set.
872   // TODO(kenton):  We can optimize this when we switch to putting all the
873   //   "has" fields into a single bitfield.
874   for (int i = 0; i < descriptor_->field_count(); i++) {
875     const FieldDescriptor* field = descriptor_->field(i);
876     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
877 
878     if (field->is_required()) {
879       printer->Print(
880         "if (!has$name$()) {\n"
881         "  memoizedIsInitialized = 0;\n"
882         "  return false;\n"
883         "}\n",
884         "name", info->capitalized_name);
885     }
886   }
887 
888   // Now check that all embedded messages are initialized.
889   for (int i = 0; i < descriptor_->field_count(); i++) {
890     const FieldDescriptor* field = descriptor_->field(i);
891     const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
892     if (GetJavaType(field) == JAVATYPE_MESSAGE &&
893         HasRequiredFields(field->message_type())) {
894       switch (field->label()) {
895         case FieldDescriptor::LABEL_REQUIRED:
896           printer->Print(
897             "if (!get$name$().isInitialized()) {\n"
898              "  memoizedIsInitialized = 0;\n"
899              "  return false;\n"
900              "}\n",
901             "type", name_resolver_->GetImmutableClassName(
902                 field->message_type()),
903             "name", info->capitalized_name);
904           break;
905         case FieldDescriptor::LABEL_OPTIONAL:
906           if (!SupportFieldPresence(descriptor_->file()) &&
907               field->containing_oneof() != NULL) {
908             const OneofDescriptor* oneof = field->containing_oneof();
909             const OneofGeneratorInfo* oneof_info =
910                 context_->GetOneofGeneratorInfo(oneof);
911             printer->Print(
912               "if ($oneof_name$Case_ == $field_number$) {\n",
913               "oneof_name", oneof_info->name,
914               "field_number", SimpleItoa(field->number()));
915           } else {
916             printer->Print(
917               "if (has$name$()) {\n",
918               "name", info->capitalized_name);
919           }
920           printer->Print(
921             "  if (!get$name$().isInitialized()) {\n"
922             "    memoizedIsInitialized = 0;\n"
923             "    return false;\n"
924             "  }\n"
925             "}\n",
926             "name", info->capitalized_name);
927           break;
928         case FieldDescriptor::LABEL_REPEATED:
929           if (IsMapEntry(field->message_type())) {
930             printer->Print(
931               "for ($type$ item : get$name$().values()) {\n"
932               "  if (!item.isInitialized()) {\n"
933               "    memoizedIsInitialized = 0;\n"
934               "    return false;\n"
935               "  }\n"
936               "}\n",
937               "type", MapValueImmutableClassdName(field->message_type(),
938                                                   name_resolver_),
939               "name", info->capitalized_name);
940           } else {
941             printer->Print(
942               "for (int i = 0; i < get$name$Count(); i++) {\n"
943               "  if (!get$name$(i).isInitialized()) {\n"
944               "    memoizedIsInitialized = 0;\n"
945               "    return false;\n"
946               "  }\n"
947               "}\n",
948               "type", name_resolver_->GetImmutableClassName(
949                   field->message_type()),
950               "name", info->capitalized_name);
951           }
952           break;
953       }
954     }
955   }
956 
957   if (descriptor_->extension_range_count() > 0) {
958     printer->Print(
959       "if (!extensionsAreInitialized()) {\n"
960       "  memoizedIsInitialized = 0;\n"
961       "  return false;\n"
962       "}\n");
963   }
964 
965   printer->Outdent();
966 
967   printer->Print(
968     "  memoizedIsInitialized = 1;\n");
969 
970   printer->Print(
971     "  return true;\n"
972     "}\n"
973     "\n");
974 }
975 
976 // ===================================================================
977 
978 namespace {
CheckHasBitsForEqualsAndHashCode(const FieldDescriptor * field)979 bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
980   if (field->is_repeated()) {
981     return false;
982   }
983   if (SupportFieldPresence(field->file())) {
984     return true;
985   }
986   return GetJavaType(field) == JAVATYPE_MESSAGE &&
987       field->containing_oneof() == NULL;
988 }
989 }  // namespace
990 
991 void ImmutableMessageGenerator::
GenerateEqualsAndHashCode(io::Printer * printer)992 GenerateEqualsAndHashCode(io::Printer* printer) {
993   printer->Print(
994     "@java.lang.Override\n"
995     "public boolean equals(final java.lang.Object obj) {\n");
996   printer->Indent();
997   printer->Print(
998     "if (obj == this) {\n"
999     " return true;\n"
1000     "}\n"
1001     "if (!(obj instanceof $classname$)) {\n"
1002     "  return super.equals(obj);\n"
1003     "}\n"
1004     "$classname$ other = ($classname$) obj;\n"
1005     "\n",
1006     "classname", name_resolver_->GetImmutableClassName(descriptor_));
1007 
1008   printer->Print("boolean result = true;\n");
1009   for (int i = 0; i < descriptor_->field_count(); i++) {
1010     const FieldDescriptor* field = descriptor_->field(i);
1011     if (field->containing_oneof() == NULL) {
1012       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1013       bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1014       if (check_has_bits) {
1015         printer->Print(
1016           "result = result && (has$name$() == other.has$name$());\n"
1017           "if (has$name$()) {\n",
1018           "name", info->capitalized_name);
1019         printer->Indent();
1020       }
1021       field_generators_.get(field).GenerateEqualsCode(printer);
1022       if (check_has_bits) {
1023         printer->Outdent();
1024         printer->Print(
1025           "}\n");
1026       }
1027     }
1028   }
1029 
1030   // Compare oneofs.
1031   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1032     printer->Print(
1033       "result = result && get$oneof_capitalized_name$Case().equals(\n"
1034       "    other.get$oneof_capitalized_name$Case());\n",
1035       "oneof_capitalized_name",
1036       context_->GetOneofGeneratorInfo(
1037           descriptor_->oneof_decl(i))->capitalized_name);
1038     printer->Print(
1039       "if (!result) return false;\n"
1040       "switch ($oneof_name$Case_) {\n",
1041       "oneof_name",
1042       context_->GetOneofGeneratorInfo(
1043           descriptor_->oneof_decl(i))->name);
1044     printer->Indent();
1045     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1046       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1047       printer->Print(
1048         "case $field_number$:\n",
1049         "field_number",
1050         SimpleItoa(field->number()));
1051       printer->Indent();
1052       field_generators_.get(field).GenerateEqualsCode(printer);
1053       printer->Print("break;\n");
1054       printer->Outdent();
1055     }
1056     printer->Print(
1057       "case 0:\n"
1058       "default:\n");
1059     printer->Outdent();
1060     printer->Print("}\n");
1061   }
1062 
1063   if (PreserveUnknownFields(descriptor_)) {
1064     // Always consider unknown fields for equality. This will sometimes return
1065     // false for non-canonical ordering when running in LITE_RUNTIME but it's
1066     // the best we can do.
1067     printer->Print(
1068       "result = result && unknownFields.equals(other.unknownFields);\n");
1069   }
1070   if (descriptor_->extension_range_count() > 0) {
1071     printer->Print(
1072       "result = result &&\n"
1073       "    getExtensionFields().equals(other.getExtensionFields());\n");
1074   }
1075   printer->Print(
1076     "return result;\n");
1077   printer->Outdent();
1078   printer->Print(
1079     "}\n"
1080     "\n");
1081 
1082   printer->Print(
1083     "@java.lang.Override\n"
1084     "public int hashCode() {\n");
1085   printer->Indent();
1086   printer->Print(
1087     "if (memoizedHashCode != 0) {\n");
1088   printer->Indent();
1089   printer->Print(
1090     "return memoizedHashCode;\n");
1091   printer->Outdent();
1092   printer->Print(
1093     "}\n"
1094     "int hash = 41;\n");
1095 
1096   printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
1097 
1098   // hashCode non-oneofs.
1099   for (int i = 0; i < descriptor_->field_count(); i++) {
1100     const FieldDescriptor* field = descriptor_->field(i);
1101     if (field->containing_oneof() == NULL) {
1102       const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
1103       bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
1104       if (check_has_bits) {
1105         printer->Print(
1106           "if (has$name$()) {\n",
1107           "name", info->capitalized_name);
1108         printer->Indent();
1109       }
1110       field_generators_.get(field).GenerateHashCode(printer);
1111       if (check_has_bits) {
1112         printer->Outdent();
1113         printer->Print("}\n");
1114       }
1115     }
1116   }
1117 
1118   // hashCode oneofs.
1119   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
1120     printer->Print(
1121       "switch ($oneof_name$Case_) {\n",
1122       "oneof_name",
1123       context_->GetOneofGeneratorInfo(
1124           descriptor_->oneof_decl(i))->name);
1125     printer->Indent();
1126     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
1127       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
1128       printer->Print(
1129         "case $field_number$:\n",
1130         "field_number",
1131         SimpleItoa(field->number()));
1132       printer->Indent();
1133       field_generators_.get(field).GenerateHashCode(printer);
1134       printer->Print("break;\n");
1135       printer->Outdent();
1136     }
1137     printer->Print(
1138       "case 0:\n"
1139       "default:\n");
1140     printer->Outdent();
1141     printer->Print("}\n");
1142   }
1143 
1144   if (descriptor_->extension_range_count() > 0) {
1145     printer->Print(
1146       "hash = hashFields(hash, getExtensionFields());\n");
1147   }
1148 
1149   printer->Print(
1150     "hash = (29 * hash) + unknownFields.hashCode();\n");
1151   printer->Print(
1152     "memoizedHashCode = hash;\n"
1153     "return hash;\n");
1154   printer->Outdent();
1155   printer->Print(
1156     "}\n"
1157     "\n");
1158 }
1159 
1160 // ===================================================================
1161 
1162 void ImmutableMessageGenerator::
GenerateExtensionRegistrationCode(io::Printer * printer)1163 GenerateExtensionRegistrationCode(io::Printer* printer) {
1164   for (int i = 0; i < descriptor_->extension_count(); i++) {
1165     ImmutableExtensionGenerator(descriptor_->extension(i), context_)
1166       .GenerateRegistrationCode(printer);
1167   }
1168 
1169   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
1170     ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
1171       .GenerateExtensionRegistrationCode(printer);
1172   }
1173 }
1174 
1175 // ===================================================================
1176 void ImmutableMessageGenerator::
GenerateParsingConstructor(io::Printer * printer)1177 GenerateParsingConstructor(io::Printer* printer) {
1178   google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields(
1179       SortFieldsByNumber(descriptor_));
1180 
1181   printer->Print(
1182       "private $classname$(\n"
1183       "    com.google.protobuf.CodedInputStream input,\n"
1184       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1185       "    throws com.google.protobuf.InvalidProtocolBufferException {\n",
1186       "classname", descriptor_->name());
1187   printer->Indent();
1188 
1189   // Initialize all fields to default.
1190   printer->Print(
1191       "this();\n");
1192 
1193   // Use builder bits to track mutable repeated fields.
1194   int totalBuilderBits = 0;
1195   for (int i = 0; i < descriptor_->field_count(); i++) {
1196     const ImmutableFieldGenerator& field =
1197         field_generators_.get(descriptor_->field(i));
1198     totalBuilderBits += field.GetNumBitsForBuilder();
1199   }
1200   int totalBuilderInts = (totalBuilderBits + 31) / 32;
1201   for (int i = 0; i < totalBuilderInts; i++) {
1202     printer->Print("int mutable_$bit_field_name$ = 0;\n",
1203       "bit_field_name", GetBitFieldName(i));
1204   }
1205 
1206   if (PreserveUnknownFields(descriptor_)) {
1207     printer->Print(
1208       "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
1209       "    com.google.protobuf.UnknownFieldSet.newBuilder();\n");
1210   }
1211 
1212   printer->Print(
1213       "try {\n");
1214   printer->Indent();
1215 
1216   printer->Print(
1217     "boolean done = false;\n"
1218     "while (!done) {\n");
1219   printer->Indent();
1220 
1221   printer->Print(
1222     "int tag = input.readTag();\n"
1223     "switch (tag) {\n");
1224   printer->Indent();
1225 
1226   printer->Print(
1227     "case 0:\n"          // zero signals EOF / limit reached
1228     "  done = true;\n"
1229     "  break;\n");
1230 
1231   if (PreserveUnknownFields(descriptor_)) {
1232     printer->Print(
1233       "default: {\n"
1234       "  if (!parseUnknownField(input, unknownFields,\n"
1235       "                         extensionRegistry, tag)) {\n"
1236       "    done = true;\n"  // it's an endgroup tag
1237       "  }\n"
1238       "  break;\n"
1239       "}\n");
1240   } else {
1241     printer->Print(
1242       "default: {\n"
1243       "  if (!input.skipField(tag)) {\n"
1244       "    done = true;\n"  // it's an endgroup tag
1245       "  }\n"
1246       "  break;\n"
1247       "}\n");
1248   }
1249 
1250   for (int i = 0; i < descriptor_->field_count(); i++) {
1251     const FieldDescriptor* field = sorted_fields[i];
1252     uint32 tag = WireFormatLite::MakeTag(field->number(),
1253       WireFormat::WireTypeForFieldType(field->type()));
1254 
1255     printer->Print(
1256       "case $tag$: {\n",
1257       "tag", SimpleItoa(tag));
1258     printer->Indent();
1259 
1260     field_generators_.get(field).GenerateParsingCode(printer);
1261 
1262     printer->Outdent();
1263     printer->Print(
1264       "  break;\n"
1265       "}\n");
1266 
1267     if (field->is_packable()) {
1268       // To make packed = true wire compatible, we generate parsing code from a
1269       // packed version of this field regardless of field->options().packed().
1270       uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
1271         WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
1272       printer->Print(
1273         "case $tag$: {\n",
1274         "tag", SimpleItoa(packed_tag));
1275       printer->Indent();
1276 
1277       field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
1278 
1279       printer->Outdent();
1280       printer->Print(
1281         "  break;\n"
1282         "}\n");
1283     }
1284   }
1285 
1286   printer->Outdent();
1287   printer->Outdent();
1288   printer->Print(
1289       "  }\n"     // switch (tag)
1290       "}\n");     // while (!done)
1291 
1292   printer->Outdent();
1293   printer->Print(
1294       "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1295       "  throw e.setUnfinishedMessage(this);\n"
1296       "} catch (java.io.IOException e) {\n"
1297       "  throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1298       "      e).setUnfinishedMessage(this);\n"
1299       "} finally {\n");
1300   printer->Indent();
1301 
1302   // Make repeated field list immutable.
1303   for (int i = 0; i < descriptor_->field_count(); i++) {
1304     const FieldDescriptor* field = sorted_fields[i];
1305     field_generators_.get(field).GenerateParsingDoneCode(printer);
1306   }
1307 
1308   if (PreserveUnknownFields(descriptor_)) {
1309     // Make unknown fields immutable.
1310     printer->Print("this.unknownFields = unknownFields.build();\n");
1311   }
1312 
1313   // Make extensions immutable.
1314   printer->Print(
1315       "makeExtensionsImmutable();\n");
1316 
1317   printer->Outdent();
1318   printer->Outdent();
1319   printer->Print(
1320       "  }\n"     // finally
1321       "}\n");
1322 }
1323 
1324 // ===================================================================
GenerateParser(io::Printer * printer)1325 void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
1326   printer->Print(
1327       "$visibility$ static final com.google.protobuf.Parser<$classname$>\n"
1328       "    PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n",
1329       "visibility",
1330       ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public"
1331                                               : "private",
1332       "classname", descriptor_->name());
1333   printer->Indent();
1334   printer->Print(
1335       "public $classname$ parsePartialFrom(\n"
1336       "    com.google.protobuf.CodedInputStream input,\n"
1337       "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
1338       "    throws com.google.protobuf.InvalidProtocolBufferException {\n",
1339       "classname", descriptor_->name());
1340   if (context_->HasGeneratedMethods(descriptor_)) {
1341     printer->Print(
1342         "    return new $classname$(input, extensionRegistry);\n",
1343         "classname", descriptor_->name());
1344   } else {
1345     // When parsing constructor isn't generated, use builder to parse
1346     // messages. Note, will fallback to use reflection based mergeFieldFrom()
1347     // in AbstractMessage.Builder.
1348     printer->Indent();
1349     printer->Print(
1350         "Builder builder = newBuilder();\n"
1351         "try {\n"
1352         "  builder.mergeFrom(input, extensionRegistry);\n"
1353         "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
1354         "  throw e.setUnfinishedMessage(builder.buildPartial());\n"
1355         "} catch (java.io.IOException e) {\n"
1356         "  throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1357         "      e.getMessage()).setUnfinishedMessage(\n"
1358         "          builder.buildPartial());\n"
1359         "}\n"
1360         "return builder.buildPartial();\n");
1361     printer->Outdent();
1362   }
1363   printer->Print(
1364         "}\n");
1365   printer->Outdent();
1366   printer->Print(
1367       "};\n"
1368       "\n");
1369 
1370   printer->Print(
1371       "public static com.google.protobuf.Parser<$classname$> parser() {\n"
1372       "  return PARSER;\n"
1373       "}\n"
1374       "\n"
1375       "@java.lang.Override\n"
1376       "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
1377       "  return PARSER;\n"
1378       "}\n"
1379       "\n",
1380       "classname", descriptor_->name());
1381 }
1382 
1383 // ===================================================================
GenerateInitializers(io::Printer * printer)1384 void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
1385   for (int i = 0; i < descriptor_->field_count(); i++) {
1386     if (!descriptor_->field(i)->containing_oneof()) {
1387       field_generators_.get(descriptor_->field(i))
1388           .GenerateInitializationCode(printer);
1389     }
1390   }
1391 }
1392 
1393 
GenerateAnyMethods(io::Printer * printer)1394 void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
1395   printer->Print(
1396     "private static String getTypeUrl(\n"
1397     "    java.lang.String typeUrlPrefix,\n"
1398     "    com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
1399     "  return typeUrlPrefix.endsWith(\"/\")\n"
1400     "      ? typeUrlPrefix + descriptor.getFullName()\n"
1401     "      : typeUrlPrefix + \"/\" + descriptor.getFullName();\n"
1402     "}\n"
1403     "\n"
1404     "private static String getTypeNameFromTypeUrl(\n"
1405     "    java.lang.String typeUrl) {\n"
1406     "  int pos = typeUrl.lastIndexOf('/');\n"
1407     "  return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n"
1408     "}\n"
1409     "\n"
1410     "public static <T extends com.google.protobuf.Message> Any pack(\n"
1411     "    T message) {\n"
1412     "  return Any.newBuilder()\n"
1413     "      .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n"
1414     "                             message.getDescriptorForType()))\n"
1415     "      .setValue(message.toByteString())\n"
1416     "      .build();\n"
1417     "}\n"
1418     "\n"
1419     "/**\n"
1420     " * Packs a message uisng the given type URL prefix. The type URL will\n"
1421     " * be constructed by concatenating the message type's full name to the\n"
1422     " * prefix with an optional \"/\" separator if the prefix doesn't end\n"
1423     " * with \"/\" already.\n"
1424     " */\n"
1425     "public static <T extends com.google.protobuf.Message> Any pack(\n"
1426     "    T message, java.lang.String typeUrlPrefix) {\n"
1427     "  return Any.newBuilder()\n"
1428     "      .setTypeUrl(getTypeUrl(typeUrlPrefix,\n"
1429     "                             message.getDescriptorForType()))\n"
1430     "      .setValue(message.toByteString())\n"
1431     "      .build();\n"
1432     "}\n"
1433     "\n"
1434     "public <T extends com.google.protobuf.Message> boolean is(\n"
1435     "    java.lang.Class<T> clazz) {\n"
1436     "  T defaultInstance =\n"
1437     "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
1438     "  return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n"
1439     "      defaultInstance.getDescriptorForType().getFullName());\n"
1440     "}\n"
1441     "\n"
1442     "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
1443     "\n"
1444     "public <T extends com.google.protobuf.Message> T unpack(\n"
1445     "    java.lang.Class<T> clazz)\n"
1446     "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
1447     "  if (!is(clazz)) {\n"
1448     "    throw new com.google.protobuf.InvalidProtocolBufferException(\n"
1449     "        \"Type of the Any message does not match the given class.\");\n"
1450     "  }\n"
1451     "  if (cachedUnpackValue != null) {\n"
1452     "    return (T) cachedUnpackValue;\n"
1453     "  }\n"
1454     "  T defaultInstance =\n"
1455     "      com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
1456     "  T result = (T) defaultInstance.getParserForType()\n"
1457     "      .parseFrom(getValue());\n"
1458     "  cachedUnpackValue = result;\n"
1459     "  return result;\n"
1460     "}\n");
1461 }
1462 
1463 }  // namespace java
1464 }  // namespace compiler
1465 }  // namespace protobuf
1466 }  // namespace google
1467