• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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 <algorithm>
36 #include <google/protobuf/stubs/hash.h>
37 #include <google/protobuf/compiler/javanano/javanano_message.h>
38 #include <google/protobuf/compiler/javanano/javanano_enum.h>
39 #include <google/protobuf/compiler/javanano/javanano_extension.h>
40 #include <google/protobuf/compiler/javanano/javanano_helpers.h>
41 #include <google/protobuf/stubs/strutil.h>
42 #include <google/protobuf/io/printer.h>
43 #include <google/protobuf/io/coded_stream.h>
44 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/descriptor.pb.h>
46 
47 namespace google {
48 namespace protobuf {
49 namespace compiler {
50 namespace javanano {
51 
52 using internal::WireFormat;
53 using internal::WireFormatLite;
54 
55 namespace {
56 
57 struct FieldOrderingByNumber {
operator ()google::protobuf::compiler::javanano::__anon7e6e964a0111::FieldOrderingByNumber58   inline bool operator()(const FieldDescriptor* a,
59                          const FieldDescriptor* b) const {
60     return a->number() < b->number();
61   }
62 };
63 
64 // Sort the fields of the given Descriptor by number into a new[]'d array
65 // and return it.
SortFieldsByNumber(const Descriptor * descriptor)66 const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
67   const FieldDescriptor** fields =
68     new const FieldDescriptor*[descriptor->field_count()];
69   for (int i = 0; i < descriptor->field_count(); i++) {
70     fields[i] = descriptor->field(i);
71   }
72   sort(fields, fields + descriptor->field_count(),
73        FieldOrderingByNumber());
74   return fields;
75 }
76 
77 }  // namespace
78 
79 // ===================================================================
80 
MessageGenerator(const Descriptor * descriptor,const Params & params)81 MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params)
82   : params_(params),
83     descriptor_(descriptor),
84     field_generators_(descriptor, params) {
85 }
86 
~MessageGenerator()87 MessageGenerator::~MessageGenerator() {}
88 
GenerateStaticVariables(io::Printer * printer)89 void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
90   // Generate static members for all nested types.
91   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
92     // TODO(kenton):  Reuse MessageGenerator objects?
93     if (IsMapEntry(descriptor_->nested_type(i))) continue;
94     MessageGenerator(descriptor_->nested_type(i), params_)
95       .GenerateStaticVariables(printer);
96   }
97 }
98 
GenerateStaticVariableInitializers(io::Printer * printer)99 void MessageGenerator::GenerateStaticVariableInitializers(
100     io::Printer* printer) {
101   // Generate static member initializers for all nested types.
102   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
103    // TODO(kenton):  Reuse MessageGenerator objects?
104     if (IsMapEntry(descriptor_->nested_type(i))) continue;
105     MessageGenerator(descriptor_->nested_type(i), params_)
106       .GenerateStaticVariableInitializers(printer);
107   }
108 }
109 
Generate(io::Printer * printer)110 void MessageGenerator::Generate(io::Printer* printer) {
111   if (!params_.store_unknown_fields() &&
112       (descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) {
113     GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the "
114         "'store_unknown_fields' generator option is 'true'\n";
115   }
116 
117   const string& file_name = descriptor_->file()->name();
118   bool is_own_file =
119     params_.java_multiple_files(file_name)
120       && descriptor_->containing_type() == NULL;
121 
122   if (is_own_file) {
123     // Note: constants (from enums and fields requiring stored defaults, emitted in the loop below)
124     // may have the same names as constants in the nested classes. This causes Java warnings, but
125     // is not fatal, so we suppress those warnings here in the top-most class declaration.
126     printer->Print(
127       "\n"
128       "@SuppressWarnings(\"hiding\")\n"
129       "public final class $classname$ extends\n",
130       "classname", descriptor_->name());
131   } else {
132     printer->Print(
133       "\n"
134       "public static final class $classname$ extends\n",
135       "classname", descriptor_->name());
136   }
137   if (params_.store_unknown_fields() && params_.parcelable_messages()) {
138     printer->Print(
139       "    com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>",
140       "classname", descriptor_->name());
141   } else if (params_.store_unknown_fields()) {
142     printer->Print(
143       "    com.google.protobuf.nano.ExtendableMessageNano<$classname$>",
144       "classname", descriptor_->name());
145   } else if (params_.parcelable_messages()) {
146     printer->Print(
147       "    com.google.protobuf.nano.android.ParcelableMessageNano");
148   } else {
149     printer->Print(
150       "    com.google.protobuf.nano.MessageNano");
151   }
152   if (params_.generate_clone()) {
153     printer->Print(" implements java.lang.Cloneable {\n");
154   } else {
155     printer->Print(" {\n");
156   }
157   printer->Indent();
158 
159   if (params_.parcelable_messages()) {
160     printer->Print(
161       "\n"
162       "// Used by Parcelable\n"
163       "@SuppressWarnings({\"unused\"})\n"
164       "public static final android.os.Parcelable.Creator<$classname$> CREATOR =\n"
165       "    new com.google.protobuf.nano.android.ParcelableMessageNanoCreator<\n"
166       "        $classname$>($classname$.class);\n",
167       "classname", descriptor_->name());
168   }
169 
170   // Nested types and extensions
171   for (int i = 0; i < descriptor_->extension_count(); i++) {
172     ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer);
173   }
174 
175   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
176     EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
177   }
178 
179   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
180     if (IsMapEntry(descriptor_->nested_type(i))) continue;
181     MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
182   }
183 
184   // oneof
185   map<string, string> vars;
186   vars["message_name"] = descriptor_->name();
187   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
188     const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i);
189     vars["oneof_name"] = UnderscoresToCamelCase(oneof_desc);
190     vars["oneof_capitalized_name"] =
191         UnderscoresToCapitalizedCamelCase(oneof_desc);
192     vars["oneof_index"] = SimpleItoa(oneof_desc->index());
193     // Oneof Constants
194     for (int j = 0; j < oneof_desc->field_count(); j++) {
195       const FieldDescriptor* field = oneof_desc->field(j);
196       vars["number"] = SimpleItoa(field->number());
197       vars["cap_field_name"] = ToUpper(field->name());
198       printer->Print(vars,
199         "public static final int $cap_field_name$_FIELD_NUMBER = $number$;\n");
200     }
201     // oneofCase_ and oneof_
202     printer->Print(vars,
203       "private int $oneof_name$Case_ = 0;\n"
204       "private java.lang.Object $oneof_name$_;\n");
205     printer->Print(vars,
206       "public int get$oneof_capitalized_name$Case() {\n"
207       "  return this.$oneof_name$Case_;\n"
208       "}\n");
209     // Oneof clear
210     printer->Print(vars,
211       "public $message_name$ clear$oneof_capitalized_name$() {\n"
212       "  this.$oneof_name$Case_ = 0;\n"
213       "  this.$oneof_name$_ = null;\n"
214       "  return this;\n"
215       "}\n");
216   }
217 
218   // Lazy initialization of otherwise static final fields can help prevent the
219   // class initializer from being generated. We want to prevent it because it
220   // stops ProGuard from inlining any methods in this class into call sites and
221   // therefore reducing the method count. However, extensions are best kept as
222   // public static final fields with initializers, so with their existence we
223   // won't bother with lazy initialization.
224   bool lazy_init = descriptor_->extension_count() == 0;
225 
226   // Empty array
227   if (lazy_init) {
228     printer->Print(
229       "\n"
230       "private static volatile $classname$[] _emptyArray;\n"
231       "public static $classname$[] emptyArray() {\n"
232       "  // Lazily initializes the empty array\n"
233       "  if (_emptyArray == null) {\n"
234       "    synchronized (\n"
235       "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
236       "      if (_emptyArray == null) {\n"
237       "        _emptyArray = new $classname$[0];\n"
238       "      }\n"
239       "    }\n"
240       "  }\n"
241       "  return _emptyArray;\n"
242       "}\n",
243       "classname", descriptor_->name());
244   } else {
245     printer->Print(
246       "\n"
247       "private static final $classname$[] EMPTY_ARRAY = {};\n"
248       "public static $classname$[] emptyArray() {\n"
249       "  return EMPTY_ARRAY;\n"
250       "}\n",
251       "classname", descriptor_->name());
252   }
253 
254   // Integers for bit fields
255   int totalInts = (field_generators_.total_bits() + 31) / 32;
256   if (totalInts > 0) {
257     printer->Print("\n");
258     for (int i = 0; i < totalInts; i++) {
259       printer->Print("private int $bit_field_name$;\n",
260         "bit_field_name", GetBitFieldName(i));
261     }
262   }
263 
264   // Fields and maybe their default values
265   for (int i = 0; i < descriptor_->field_count(); i++) {
266     printer->Print("\n");
267     PrintFieldComment(printer, descriptor_->field(i));
268     field_generators_.get(descriptor_->field(i)).GenerateMembers(
269         printer, lazy_init);
270   }
271 
272   // Constructor, with lazy init code if needed
273   if (lazy_init && field_generators_.saved_defaults_needed()) {
274     printer->Print(
275       "\n"
276       "private static volatile boolean _classInitialized;\n"
277       "\n"
278       "public $classname$() {\n"
279       "  // Lazily initializes the field defaults\n"
280       "  if (!_classInitialized) {\n"
281       "    synchronized (\n"
282       "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
283       "      if (!_classInitialized) {\n",
284       "classname", descriptor_->name());
285     printer->Indent();
286     printer->Indent();
287     printer->Indent();
288     printer->Indent();
289     for (int i = 0; i < descriptor_->field_count(); i++) {
290       field_generators_.get(descriptor_->field(i))
291           .GenerateInitSavedDefaultCode(printer);
292     }
293     printer->Outdent();
294     printer->Outdent();
295     printer->Outdent();
296     printer->Outdent();
297     printer->Print(
298       "        _classInitialized = true;\n"
299       "      }\n"
300       "    }\n"
301       "  }\n");
302     if (params_.generate_clear()) {
303       printer->Print("  clear();\n");
304     }
305     printer->Print("}\n");
306   } else {
307     printer->Print(
308       "\n"
309       "public $classname$() {\n",
310       "classname", descriptor_->name());
311     if (params_.generate_clear()) {
312       printer->Print("  clear();\n");
313     } else {
314       printer->Indent();
315       GenerateFieldInitializers(printer);
316       printer->Outdent();
317     }
318     printer->Print("}\n");
319   }
320 
321   // Other methods in this class
322 
323   GenerateClear(printer);
324 
325   if (params_.generate_clone()) {
326     GenerateClone(printer);
327   }
328 
329   if (params_.generate_equals()) {
330     GenerateEquals(printer);
331     GenerateHashCode(printer);
332   }
333 
334   GenerateMessageSerializationMethods(printer);
335   GenerateMergeFromMethods(printer);
336   GenerateParseFromMethods(printer);
337 
338   printer->Outdent();
339   printer->Print("}\n");
340 }
341 
342 // ===================================================================
343 
344 void MessageGenerator::
GenerateMessageSerializationMethods(io::Printer * printer)345 GenerateMessageSerializationMethods(io::Printer* printer) {
346   // Rely on the parent implementations of writeTo() and getSerializedSize()
347   // if there are no fields to serialize in this message.
348   if (descriptor_->field_count() == 0) {
349     return;
350   }
351 
352   scoped_array<const FieldDescriptor*> sorted_fields(
353     SortFieldsByNumber(descriptor_));
354 
355   printer->Print(
356     "\n"
357     "@Override\n"
358     "public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n"
359     "    throws java.io.IOException {\n");
360   printer->Indent();
361 
362   // Output the fields in sorted order
363   for (int i = 0; i < descriptor_->field_count(); i++) {
364     GenerateSerializeOneField(printer, sorted_fields[i]);
365   }
366 
367   // The parent implementation will write any unknown fields if necessary.
368   printer->Print(
369     "super.writeTo(output);\n");
370 
371   printer->Outdent();
372   printer->Print("}\n");
373 
374   // The parent implementation will get the serialized size for unknown
375   // fields if necessary.
376   printer->Print(
377     "\n"
378     "@Override\n"
379     "protected int computeSerializedSize() {\n"
380     "  int size = super.computeSerializedSize();\n");
381   printer->Indent();
382 
383   for (int i = 0; i < descriptor_->field_count(); i++) {
384     field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
385   }
386 
387   printer->Outdent();
388   printer->Print(
389     "  return size;\n"
390     "}\n");
391 }
392 
GenerateMergeFromMethods(io::Printer * printer)393 void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
394   scoped_array<const FieldDescriptor*> sorted_fields(
395     SortFieldsByNumber(descriptor_));
396 
397   printer->Print(
398     "\n"
399     "@Override\n"
400     "public $classname$ mergeFrom(\n"
401     "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
402     "    throws java.io.IOException {\n",
403     "classname", descriptor_->name());
404 
405   printer->Indent();
406   if (HasMapField(descriptor_)) {
407     printer->Print(
408       "com.google.protobuf.nano.MapFactories.MapFactory mapFactory =\n"
409       "  com.google.protobuf.nano.MapFactories.getMapFactory();\n");
410   }
411 
412   printer->Print(
413     "while (true) {\n");
414   printer->Indent();
415 
416   printer->Print(
417     "int tag = input.readTag();\n"
418     "switch (tag) {\n");
419   printer->Indent();
420 
421   printer->Print(
422     "case 0:\n"          // zero signals EOF / limit reached
423     "  return this;\n"
424     "default: {\n");
425 
426   printer->Indent();
427   if (params_.store_unknown_fields()) {
428     printer->Print(
429         "if (!storeUnknownField(input, tag)) {\n"
430         "  return this;\n"
431         "}\n");
432   } else {
433     printer->Print(
434         "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n"
435         "  return this;\n"   // it's an endgroup tag
436         "}\n");
437   }
438   printer->Print("break;\n");
439   printer->Outdent();
440   printer->Print("}\n");
441 
442   for (int i = 0; i < descriptor_->field_count(); i++) {
443     const FieldDescriptor* field = sorted_fields[i];
444     uint32 tag = WireFormatLite::MakeTag(field->number(),
445       WireFormat::WireTypeForFieldType(field->type()));
446 
447     printer->Print(
448       "case $tag$: {\n",
449       "tag", SimpleItoa(tag));
450     printer->Indent();
451 
452     field_generators_.get(field).GenerateMergingCode(printer);
453 
454     printer->Outdent();
455     printer->Print(
456       "  break;\n"
457       "}\n");
458 
459     if (field->is_packable()) {
460       // To make packed = true wire compatible, we generate parsing code from a
461       // packed version of this field regardless of field->options().packed().
462       uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
463         WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
464       printer->Print(
465         "case $tag$: {\n",
466         "tag", SimpleItoa(packed_tag));
467       printer->Indent();
468 
469       field_generators_.get(field).GenerateMergingCodeFromPacked(printer);
470 
471       printer->Outdent();
472       printer->Print(
473         "  break;\n"
474         "}\n");
475     }
476   }
477 
478   printer->Outdent();
479   printer->Outdent();
480   printer->Outdent();
481   printer->Print(
482     "    }\n"     // switch (tag)
483     "  }\n"       // while (true)
484     "}\n");
485 }
486 
487 void MessageGenerator::
GenerateParseFromMethods(io::Printer * printer)488 GenerateParseFromMethods(io::Printer* printer) {
489   // Note:  These are separate from GenerateMessageSerializationMethods()
490   //   because they need to be generated even for messages that are optimized
491   //   for code size.
492   printer->Print(
493     "\n"
494     "public static $classname$ parseFrom(byte[] data)\n"
495     "    throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n"
496     "  return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n"
497     "}\n"
498     "\n"
499     "public static $classname$ parseFrom(\n"
500     "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
501     "    throws java.io.IOException {\n"
502     "  return new $classname$().mergeFrom(input);\n"
503     "}\n",
504     "classname", descriptor_->name());
505 }
506 
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)507 void MessageGenerator::GenerateSerializeOneField(
508     io::Printer* printer, const FieldDescriptor* field) {
509   field_generators_.get(field).GenerateSerializationCode(printer);
510 }
511 
GenerateClear(io::Printer * printer)512 void MessageGenerator::GenerateClear(io::Printer* printer) {
513   if (!params_.generate_clear()) {
514     return;
515   }
516   printer->Print(
517     "\n"
518     "public $classname$ clear() {\n",
519     "classname", descriptor_->name());
520   printer->Indent();
521 
522   GenerateFieldInitializers(printer);
523 
524   printer->Outdent();
525   printer->Print(
526     "  return this;\n"
527     "}\n");
528 }
529 
GenerateFieldInitializers(io::Printer * printer)530 void MessageGenerator::GenerateFieldInitializers(io::Printer* printer) {
531   // Clear bit fields.
532   int totalInts = (field_generators_.total_bits() + 31) / 32;
533   for (int i = 0; i < totalInts; i++) {
534     printer->Print("$bit_field_name$ = 0;\n",
535       "bit_field_name", GetBitFieldName(i));
536   }
537 
538   // Call clear for all of the fields.
539   for (int i = 0; i < descriptor_->field_count(); i++) {
540     const FieldDescriptor* field = descriptor_->field(i);
541     field_generators_.get(field).GenerateClearCode(printer);
542   }
543 
544   // Clear oneofs.
545   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
546     printer->Print(
547       "clear$oneof_capitalized_name$();\n",
548       "oneof_capitalized_name", UnderscoresToCapitalizedCamelCase(
549           descriptor_->oneof_decl(i)));
550   }
551 
552   // Clear unknown fields.
553   if (params_.store_unknown_fields()) {
554     printer->Print("unknownFieldData = null;\n");
555   }
556   printer->Print("cachedSize = -1;\n");
557 }
558 
GenerateClone(io::Printer * printer)559 void MessageGenerator::GenerateClone(io::Printer* printer) {
560   printer->Print(
561     "@Override\n"
562     "public $classname$ clone() {\n",
563     "classname", descriptor_->name());
564   printer->Indent();
565 
566   printer->Print(
567     "$classname$ cloned;\n"
568     "try {\n"
569     "  cloned = ($classname$) super.clone();\n"
570     "} catch (java.lang.CloneNotSupportedException e) {\n"
571     "  throw new java.lang.AssertionError(e);\n"
572     "}\n",
573     "classname", descriptor_->name());
574 
575   for (int i = 0; i < descriptor_->field_count(); i++) {
576     field_generators_.get(descriptor_->field(i)).GenerateFixClonedCode(printer);
577   }
578 
579   printer->Outdent();
580   printer->Print(
581     "  return cloned;\n"
582     "}\n"
583     "\n");
584 }
585 
GenerateEquals(io::Printer * printer)586 void MessageGenerator::GenerateEquals(io::Printer* printer) {
587   // Don't override if there are no fields. We could generate an
588   // equals method that compares types, but often empty messages
589   // are used as namespaces.
590   if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
591     return;
592   }
593 
594   printer->Print(
595     "\n"
596     "@Override\n"
597     "public boolean equals(Object o) {\n");
598   printer->Indent();
599   printer->Print(
600     "if (o == this) {\n"
601     "  return true;\n"
602     "}\n"
603     "if (!(o instanceof $classname$)) {\n"
604     "  return false;\n"
605     "}\n"
606     "$classname$ other = ($classname$) o;\n",
607     "classname", descriptor_->name());
608 
609   // Checking oneof case before checking each oneof field.
610   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
611     const OneofDescriptor* oneof_desc = descriptor_->oneof_decl(i);
612     printer->Print(
613       "if (this.$oneof_name$Case_ != other.$oneof_name$Case_) {\n"
614       "  return false;\n"
615       "}\n",
616       "oneof_name", UnderscoresToCamelCase(oneof_desc));
617   }
618 
619   for (int i = 0; i < descriptor_->field_count(); i++) {
620     const FieldDescriptor* field = descriptor_->field(i);
621     field_generators_.get(field).GenerateEqualsCode(printer);
622   }
623 
624   if (params_.store_unknown_fields()) {
625     printer->Print(
626       "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n"
627       "  return other.unknownFieldData == null || other.unknownFieldData.isEmpty();\n"
628       "} else {\n"
629       "  return unknownFieldData.equals(other.unknownFieldData);\n"
630       "}");
631   } else {
632     printer->Print(
633       "return true;\n");
634   }
635 
636   printer->Outdent();
637   printer->Print("}\n");
638 }
639 
GenerateHashCode(io::Printer * printer)640 void MessageGenerator::GenerateHashCode(io::Printer* printer) {
641   if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
642     return;
643   }
644 
645   printer->Print(
646     "\n"
647     "@Override\n"
648     "public int hashCode() {\n");
649   printer->Indent();
650 
651   printer->Print("int result = 17;\n");
652   printer->Print("result = 31 * result + getClass().getName().hashCode();\n");
653   for (int i = 0; i < descriptor_->field_count(); i++) {
654     const FieldDescriptor* field = descriptor_->field(i);
655     field_generators_.get(field).GenerateHashCodeCode(printer);
656   }
657 
658   if (params_.store_unknown_fields()) {
659     printer->Print(
660       "result = 31 * result + \n"
661       "  (unknownFieldData == null || unknownFieldData.isEmpty() ? 0 : \n"
662       "  unknownFieldData.hashCode());\n");
663   }
664 
665   printer->Print("return result;\n");
666 
667   printer->Outdent();
668   printer->Print("}\n");
669 }
670 
671 // ===================================================================
672 
673 }  // namespace javanano
674 }  // namespace compiler
675 }  // namespace protobuf
676 }  // namespace google
677