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