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
47namespace google {
48namespace protobuf {
49namespace compiler {
50namespace javanano {
51
52using internal::WireFormat;
53using internal::WireFormatLite;
54
55namespace {
56
57struct FieldOrderingByNumber {
58  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.
66const 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
81MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params)
82  : params_(params),
83    descriptor_(descriptor),
84    field_generators_(descriptor, params) {
85}
86
87MessageGenerator::~MessageGenerator() {}
88
89void 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
99void 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
110void 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
344void MessageGenerator::
345GenerateMessageSerializationMethods(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
393void 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
487void MessageGenerator::
488GenerateParseFromMethods(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
507void MessageGenerator::GenerateSerializeOneField(
508    io::Printer* printer, const FieldDescriptor* field) {
509  field_generators_.get(field).GenerateSerializationCode(printer);
510}
511
512void 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
530void 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
559void 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
586void 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
640void 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