• 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::__anon039cca180111::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     MessageGenerator(descriptor_->nested_type(i), params_)
94       .GenerateStaticVariables(printer);
95   }
96 }
97 
GenerateStaticVariableInitializers(io::Printer * printer)98 void MessageGenerator::GenerateStaticVariableInitializers(
99     io::Printer* printer) {
100   // Generate static member initializers for all nested types.
101   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
102    // TODO(kenton):  Reuse MessageGenerator objects?
103     MessageGenerator(descriptor_->nested_type(i), params_)
104       .GenerateStaticVariableInitializers(printer);
105   }
106 }
107 
Generate(io::Printer * printer)108 void MessageGenerator::Generate(io::Printer* printer) {
109   if (!params_.store_unknown_fields() &&
110       (descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) {
111     GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the "
112         "'store_unknown_fields' generator option is 'true'\n";
113   }
114 
115   const string& file_name = descriptor_->file()->name();
116   bool is_own_file =
117     params_.java_multiple_files(file_name)
118       && descriptor_->containing_type() == NULL;
119 
120   if (is_own_file) {
121     // Note: constants (from enums and fields requiring stored defaults, emitted in the loop below)
122     // may have the same names as constants in the nested classes. This causes Java warnings, but
123     // is not fatal, so we suppress those warnings here in the top-most class declaration.
124     printer->Print(
125       "\n"
126       "@SuppressWarnings(\"hiding\")\n"
127       "public final class $classname$ extends\n",
128       "classname", descriptor_->name());
129   } else {
130     printer->Print(
131       "\n"
132       "public static final class $classname$ extends\n",
133       "classname", descriptor_->name());
134   }
135   if (params_.store_unknown_fields() && params_.parcelable_messages()) {
136     printer->Print(
137       "    com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$> {\n",
138       "classname", descriptor_->name());
139   } else if (params_.store_unknown_fields()) {
140     printer->Print(
141       "    com.google.protobuf.nano.ExtendableMessageNano<$classname$> {\n",
142       "classname", descriptor_->name());
143   } else if (params_.parcelable_messages()) {
144     printer->Print(
145       "    com.google.protobuf.nano.android.ParcelableMessageNano {\n");
146   } else {
147     printer->Print(
148       "    com.google.protobuf.nano.MessageNano {\n");
149   }
150   printer->Indent();
151 
152   // Nested types and extensions
153   for (int i = 0; i < descriptor_->extension_count(); i++) {
154     ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer);
155   }
156 
157   for (int i = 0; i < descriptor_->enum_type_count(); i++) {
158     EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
159   }
160 
161   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
162     MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
163   }
164 
165   // Lazy initialization of otherwise static final fields can help prevent the
166   // class initializer from being generated. We want to prevent it because it
167   // stops ProGuard from inlining any methods in this class into call sites and
168   // therefore reducing the method count. However, extensions are best kept as
169   // public static final fields with initializers, so with their existence we
170   // won't bother with lazy initialization.
171   bool lazy_init = descriptor_->extension_count() == 0;
172 
173   // Empty array
174   if (lazy_init) {
175     printer->Print(
176       "\n"
177       "private static volatile $classname$[] _emptyArray;\n"
178       "public static $classname$[] emptyArray() {\n"
179       "  // Lazily initializes the empty array\n"
180       "  if (_emptyArray == null) {\n"
181       "    synchronized (\n"
182       "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
183       "      if (_emptyArray == null) {\n"
184       "        _emptyArray = new $classname$[0];\n"
185       "      }\n"
186       "    }\n"
187       "  }\n"
188       "  return _emptyArray;\n"
189       "}\n",
190       "classname", descriptor_->name());
191   } else {
192     printer->Print(
193       "\n"
194       "private static final $classname$[] EMPTY_ARRAY = {};\n"
195       "public static $classname$[] emptyArray() {\n"
196       "  return EMPTY_ARRAY;\n"
197       "}\n",
198       "classname", descriptor_->name());
199   }
200 
201   // Integers for bit fields
202   int totalInts = (field_generators_.total_bits() + 31) / 32;
203   if (totalInts > 0) {
204     printer->Print("\n");
205     for (int i = 0; i < totalInts; i++) {
206       printer->Print("private int $bit_field_name$;\n",
207         "bit_field_name", GetBitFieldName(i));
208     }
209   }
210 
211   // Fields and maybe their default values
212   for (int i = 0; i < descriptor_->field_count(); i++) {
213     printer->Print("\n");
214     PrintFieldComment(printer, descriptor_->field(i));
215     field_generators_.get(descriptor_->field(i)).GenerateMembers(
216         printer, lazy_init);
217   }
218 
219   // Constructor, with lazy init code if needed
220   if (lazy_init && field_generators_.saved_defaults_needed()) {
221     printer->Print(
222       "\n"
223       "private static volatile boolean _classInitialized;\n"
224       "\n"
225       "public $classname$() {\n"
226       "  // Lazily initializes the field defaults\n"
227       "  if (!_classInitialized) {\n"
228       "    synchronized (\n"
229       "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
230       "      if (!_classInitialized) {\n",
231       "classname", descriptor_->name());
232     printer->Indent();
233     printer->Indent();
234     printer->Indent();
235     printer->Indent();
236     for (int i = 0; i < descriptor_->field_count(); i++) {
237       field_generators_.get(descriptor_->field(i))
238           .GenerateInitSavedDefaultCode(printer);
239     }
240     printer->Outdent();
241     printer->Outdent();
242     printer->Outdent();
243     printer->Outdent();
244     printer->Print(
245       "        _classInitialized = true;\n"
246       "      }\n"
247       "    }\n"
248       "  }\n"
249       "  clear();\n"
250       "}\n");
251   } else {
252     printer->Print(
253       "\n"
254       "public $classname$() {\n"
255       "  clear();\n"
256       "}\n",
257       "classname", descriptor_->name());
258   }
259 
260   // Other methods in this class
261 
262   GenerateClear(printer);
263 
264   if (params_.generate_equals()) {
265     GenerateEquals(printer);
266     GenerateHashCode(printer);
267   }
268 
269   GenerateMessageSerializationMethods(printer);
270   GenerateMergeFromMethods(printer);
271   GenerateParseFromMethods(printer);
272 
273   printer->Outdent();
274   printer->Print("}\n");
275 }
276 
277 // ===================================================================
278 
279 void MessageGenerator::
GenerateMessageSerializationMethods(io::Printer * printer)280 GenerateMessageSerializationMethods(io::Printer* printer) {
281   // Rely on the parent implementations of writeTo() and getSerializedSize()
282   // if there are no fields to serialize in this message.
283   if (descriptor_->field_count() == 0) {
284     return;
285   }
286 
287   scoped_array<const FieldDescriptor*> sorted_fields(
288     SortFieldsByNumber(descriptor_));
289 
290   printer->Print(
291     "\n"
292     "@Override\n"
293     "public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n"
294     "    throws java.io.IOException {\n");
295   printer->Indent();
296 
297   // Output the fields in sorted order
298   for (int i = 0; i < descriptor_->field_count(); i++) {
299     GenerateSerializeOneField(printer, sorted_fields[i]);
300   }
301 
302   // The parent implementation will write any unknown fields if necessary.
303   printer->Print(
304     "super.writeTo(output);\n");
305 
306   printer->Outdent();
307   printer->Print("}\n");
308 
309   // The parent implementation will get the serialized size for unknown
310   // fields if necessary.
311   printer->Print(
312     "\n"
313     "@Override\n"
314     "protected int computeSerializedSize() {\n"
315     "  int size = super.computeSerializedSize();\n");
316   printer->Indent();
317 
318   for (int i = 0; i < descriptor_->field_count(); i++) {
319     field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
320   }
321 
322   printer->Outdent();
323   printer->Print(
324     "  return size;\n"
325     "}\n");
326 }
327 
GenerateMergeFromMethods(io::Printer * printer)328 void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
329   scoped_array<const FieldDescriptor*> sorted_fields(
330     SortFieldsByNumber(descriptor_));
331 
332   printer->Print(
333     "\n"
334     "@Override\n"
335     "public $classname$ mergeFrom(\n"
336     "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
337     "    throws java.io.IOException {\n",
338     "classname", descriptor_->name());
339 
340   printer->Indent();
341 
342   printer->Print(
343     "while (true) {\n");
344   printer->Indent();
345 
346   printer->Print(
347     "int tag = input.readTag();\n"
348     "switch (tag) {\n");
349   printer->Indent();
350 
351   printer->Print(
352     "case 0:\n"          // zero signals EOF / limit reached
353     "  return this;\n"
354     "default: {\n");
355 
356   printer->Indent();
357   if (params_.store_unknown_fields()) {
358     printer->Print(
359         "if (!storeUnknownField(input, tag)) {\n"
360         "  return this;\n"
361         "}\n");
362   } else {
363     printer->Print(
364         "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n"
365         "  return this;\n"   // it's an endgroup tag
366         "}\n");
367   }
368   printer->Print("break;\n");
369   printer->Outdent();
370   printer->Print("}\n");
371 
372   for (int i = 0; i < descriptor_->field_count(); i++) {
373     const FieldDescriptor* field = sorted_fields[i];
374     uint32 tag = WireFormatLite::MakeTag(field->number(),
375       WireFormat::WireTypeForFieldType(field->type()));
376 
377     printer->Print(
378       "case $tag$: {\n",
379       "tag", SimpleItoa(tag));
380     printer->Indent();
381 
382     field_generators_.get(field).GenerateMergingCode(printer);
383 
384     printer->Outdent();
385     printer->Print(
386       "  break;\n"
387       "}\n");
388 
389     if (field->is_packable()) {
390       // To make packed = true wire compatible, we generate parsing code from a
391       // packed version of this field regardless of field->options().packed().
392       uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
393         WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
394       printer->Print(
395         "case $tag$: {\n",
396         "tag", SimpleItoa(packed_tag));
397       printer->Indent();
398 
399       field_generators_.get(field).GenerateMergingCodeFromPacked(printer);
400 
401       printer->Outdent();
402       printer->Print(
403         "  break;\n"
404         "}\n");
405     }
406   }
407 
408   printer->Outdent();
409   printer->Outdent();
410   printer->Outdent();
411   printer->Print(
412     "    }\n"     // switch (tag)
413     "  }\n"       // while (true)
414     "}\n");
415 }
416 
417 void MessageGenerator::
GenerateParseFromMethods(io::Printer * printer)418 GenerateParseFromMethods(io::Printer* printer) {
419   // Note:  These are separate from GenerateMessageSerializationMethods()
420   //   because they need to be generated even for messages that are optimized
421   //   for code size.
422   printer->Print(
423     "\n"
424     "public static $classname$ parseFrom(byte[] data)\n"
425     "    throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n"
426     "  return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n"
427     "}\n"
428     "\n"
429     "public static $classname$ parseFrom(\n"
430     "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
431     "    throws java.io.IOException {\n"
432     "  return new $classname$().mergeFrom(input);\n"
433     "}\n",
434     "classname", descriptor_->name());
435 }
436 
GenerateSerializeOneField(io::Printer * printer,const FieldDescriptor * field)437 void MessageGenerator::GenerateSerializeOneField(
438     io::Printer* printer, const FieldDescriptor* field) {
439   field_generators_.get(field).GenerateSerializationCode(printer);
440 }
441 
GenerateClear(io::Printer * printer)442 void MessageGenerator::GenerateClear(io::Printer* printer) {
443   printer->Print(
444     "\n"
445     "public $classname$ clear() {\n",
446     "classname", descriptor_->name());
447   printer->Indent();
448 
449   // Clear bit fields.
450   int totalInts = (field_generators_.total_bits() + 31) / 32;
451   for (int i = 0; i < totalInts; i++) {
452     printer->Print("$bit_field_name$ = 0;\n",
453       "bit_field_name", GetBitFieldName(i));
454   }
455 
456   // Call clear for all of the fields.
457   for (int i = 0; i < descriptor_->field_count(); i++) {
458     const FieldDescriptor* field = descriptor_->field(i);
459     field_generators_.get(field).GenerateClearCode(printer);
460   }
461 
462   // Clear unknown fields.
463   if (params_.store_unknown_fields()) {
464     printer->Print("unknownFieldData = null;\n");
465   }
466 
467   printer->Outdent();
468   printer->Print(
469     "  cachedSize = -1;\n"
470     "  return this;\n"
471     "}\n");
472 }
473 
GenerateEquals(io::Printer * printer)474 void MessageGenerator::GenerateEquals(io::Printer* printer) {
475   // Don't override if there are no fields. We could generate an
476   // equals method that compares types, but often empty messages
477   // are used as namespaces.
478   if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
479     return;
480   }
481 
482   printer->Print(
483     "\n"
484     "@Override\n"
485     "public boolean equals(Object o) {\n");
486   printer->Indent();
487   printer->Print(
488     "if (o == this) {\n"
489     "  return true;\n"
490     "}\n"
491     "if (!(o instanceof $classname$)) {\n"
492     "  return false;\n"
493     "}\n"
494     "$classname$ other = ($classname$) o;\n",
495     "classname", descriptor_->name());
496 
497   for (int i = 0; i < descriptor_->field_count(); i++) {
498     const FieldDescriptor* field = descriptor_->field(i);
499     field_generators_.get(field).GenerateEqualsCode(printer);
500   }
501 
502   if (params_.store_unknown_fields()) {
503     printer->Print(
504       "return unknownFieldDataEquals(other);\n");
505   } else {
506     printer->Print(
507       "return true;\n");
508   }
509 
510   printer->Outdent();
511   printer->Print("}\n");
512 }
513 
GenerateHashCode(io::Printer * printer)514 void MessageGenerator::GenerateHashCode(io::Printer* printer) {
515   if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
516     return;
517   }
518 
519   printer->Print(
520     "\n"
521     "@Override\n"
522     "public int hashCode() {\n");
523   printer->Indent();
524 
525   printer->Print("int result = 17;\n");
526   for (int i = 0; i < descriptor_->field_count(); i++) {
527     const FieldDescriptor* field = descriptor_->field(i);
528     field_generators_.get(field).GenerateHashCodeCode(printer);
529   }
530 
531   if (params_.store_unknown_fields()) {
532     printer->Print(
533       "result = 31 * result + unknownFieldDataHashCode();\n");
534   }
535 
536   printer->Print("return result;\n");
537 
538   printer->Outdent();
539   printer->Print("}\n");
540 }
541 
542 // ===================================================================
543 
544 }  // namespace javanano
545 }  // namespace compiler
546 }  // namespace protobuf
547 }  // namespace google
548