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 <map>
36 #include <math.h>
37 #include <string>
38 
39 #include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/compiler/javanano/javanano_helpers.h>
42 #include <google/protobuf/io/printer.h>
43 #include <google/protobuf/wire_format.h>
44 #include <google/protobuf/stubs/strutil.h>
45 #include <google/protobuf/stubs/substitute.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 
IsReferenceType(JavaType type)57 bool IsReferenceType(JavaType type) {
58   switch (type) {
59     case JAVATYPE_INT    : return false;
60     case JAVATYPE_LONG   : return false;
61     case JAVATYPE_FLOAT  : return false;
62     case JAVATYPE_DOUBLE : return false;
63     case JAVATYPE_BOOLEAN: return false;
64     case JAVATYPE_STRING : return true;
65     case JAVATYPE_BYTES  : return true;
66     case JAVATYPE_ENUM   : return false;
67     case JAVATYPE_MESSAGE: return true;
68 
69     // No default because we want the compiler to complain if any new
70     // JavaTypes are added.
71   }
72 
73   GOOGLE_LOG(FATAL) << "Can't get here.";
74   return false;
75 }
76 
IsArrayType(JavaType type)77 bool IsArrayType(JavaType type) {
78   switch (type) {
79     case JAVATYPE_INT    : return false;
80     case JAVATYPE_LONG   : return false;
81     case JAVATYPE_FLOAT  : return false;
82     case JAVATYPE_DOUBLE : return false;
83     case JAVATYPE_BOOLEAN: return false;
84     case JAVATYPE_STRING : return false;
85     case JAVATYPE_BYTES  : return true;
86     case JAVATYPE_ENUM   : return false;
87     case JAVATYPE_MESSAGE: return false;
88 
89     // No default because we want the compiler to complain if any new
90     // JavaTypes are added.
91   }
92 
93   GOOGLE_LOG(FATAL) << "Can't get here.";
94   return false;
95 }
96 
GetCapitalizedType(const FieldDescriptor * field)97 const char* GetCapitalizedType(const FieldDescriptor* field) {
98   switch (field->type()) {
99     case FieldDescriptor::TYPE_INT32   : return "Int32"   ;
100     case FieldDescriptor::TYPE_UINT32  : return "UInt32"  ;
101     case FieldDescriptor::TYPE_SINT32  : return "SInt32"  ;
102     case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
103     case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
104     case FieldDescriptor::TYPE_INT64   : return "Int64"   ;
105     case FieldDescriptor::TYPE_UINT64  : return "UInt64"  ;
106     case FieldDescriptor::TYPE_SINT64  : return "SInt64"  ;
107     case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
108     case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
109     case FieldDescriptor::TYPE_FLOAT   : return "Float"   ;
110     case FieldDescriptor::TYPE_DOUBLE  : return "Double"  ;
111     case FieldDescriptor::TYPE_BOOL    : return "Bool"    ;
112     case FieldDescriptor::TYPE_STRING  : return "String"  ;
113     case FieldDescriptor::TYPE_BYTES   : return "Bytes"   ;
114     case FieldDescriptor::TYPE_ENUM    : return "Enum"    ;
115     case FieldDescriptor::TYPE_GROUP   : return "Group"   ;
116     case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
117 
118     // No default because we want the compiler to complain if any new
119     // types are added.
120   }
121 
122   GOOGLE_LOG(FATAL) << "Can't get here.";
123   return NULL;
124 }
125 
126 // For encodings with fixed sizes, returns that size in bytes.  Otherwise
127 // returns -1.
FixedSize(FieldDescriptor::Type type)128 int FixedSize(FieldDescriptor::Type type) {
129   switch (type) {
130     case FieldDescriptor::TYPE_INT32   : return -1;
131     case FieldDescriptor::TYPE_INT64   : return -1;
132     case FieldDescriptor::TYPE_UINT32  : return -1;
133     case FieldDescriptor::TYPE_UINT64  : return -1;
134     case FieldDescriptor::TYPE_SINT32  : return -1;
135     case FieldDescriptor::TYPE_SINT64  : return -1;
136     case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
137     case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
138     case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
139     case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
140     case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
141     case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
142 
143     case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
144     case FieldDescriptor::TYPE_ENUM    : return -1;
145 
146     case FieldDescriptor::TYPE_STRING  : return -1;
147     case FieldDescriptor::TYPE_BYTES   : return -1;
148     case FieldDescriptor::TYPE_GROUP   : return -1;
149     case FieldDescriptor::TYPE_MESSAGE : return -1;
150 
151     // No default because we want the compiler to complain if any new
152     // types are added.
153   }
154   GOOGLE_LOG(FATAL) << "Can't get here.";
155   return -1;
156 }
157 
AllAscii(const string & text)158 bool AllAscii(const string& text) {
159   for (int i = 0; i < text.size(); i++) {
160     if ((text[i] & 0x80) != 0) {
161       return false;
162     }
163   }
164   return true;
165 }
166 
167 
SetPrimitiveVariables(const FieldDescriptor * descriptor,const Params params,map<string,string> * variables)168 void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
169                            map<string, string>* variables) {
170   (*variables)["name"] =
171     RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
172   (*variables)["capitalized_name"] =
173     RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
174   (*variables)["number"] = SimpleItoa(descriptor->number());
175   if (params.use_reference_types_for_primitives()
176       && !descriptor->is_repeated()) {
177     (*variables)["type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
178   } else {
179     (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
180   }
181   // Deals with defaults. For C++-string types (string and bytes),
182   // we might need to have the generated code do the unicode decoding
183   // (see comments in InternalNano.java for gory details.). We would
184   // like to do this once into a static field and re-use that from
185   // then on.
186   if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
187       !descriptor->default_value_string().empty() &&
188       !params.use_reference_types_for_primitives()) {
189     if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
190       (*variables)["default"] = DefaultValue(params, descriptor);
191       (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
192       (*variables)["default_constant_value"] = strings::Substitute(
193           "com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
194           CEscape(descriptor->default_value_string()));
195       (*variables)["default_copy_if_needed"] =
196           (*variables)["default"] + ".clone()";
197     } else if (AllAscii(descriptor->default_value_string())) {
198       // All chars are ASCII.  In this case directly referencing a
199       // CEscape()'d string literal works fine.
200       (*variables)["default"] =
201           "\"" + CEscape(descriptor->default_value_string()) + "\"";
202       (*variables)["default_copy_if_needed"] = (*variables)["default"];
203     } else {
204       // Strings where some chars are non-ASCII. We need to save the
205       // default value.
206       (*variables)["default"] = DefaultValue(params, descriptor);
207       (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
208       (*variables)["default_constant_value"] = strings::Substitute(
209           "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
210           CEscape(descriptor->default_value_string()));
211       (*variables)["default_copy_if_needed"] = (*variables)["default"];
212     }
213   } else {
214     // Non-string, non-bytes field. Defaults are literals.
215     (*variables)["default"] = DefaultValue(params, descriptor);
216     (*variables)["default_copy_if_needed"] = (*variables)["default"];
217   }
218   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
219   (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
220   (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
221   (*variables)["tag_size"] = SimpleItoa(
222       WireFormat::TagSize(descriptor->number(), descriptor->type()));
223   (*variables)["non_packed_tag"] = SimpleItoa(
224       internal::WireFormatLite::MakeTag(descriptor->number(),
225           internal::WireFormat::WireTypeForFieldType(descriptor->type())));
226   int fixed_size = FixedSize(descriptor->type());
227   if (fixed_size != -1) {
228     (*variables)["fixed_size"] = SimpleItoa(fixed_size);
229   }
230   (*variables)["message_name"] = descriptor->containing_type()->name();
231   (*variables)["empty_array_name"] = EmptyArrayName(params, descriptor);
232 }
233 }  // namespace
234 
235 // ===================================================================
236 
237 PrimitiveFieldGenerator::
PrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params)238 PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
239   : FieldGenerator(params), descriptor_(descriptor) {
240   SetPrimitiveVariables(descriptor, params, &variables_);
241 }
242 
~PrimitiveFieldGenerator()243 PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
244 
SavedDefaultNeeded() const245 bool PrimitiveFieldGenerator::SavedDefaultNeeded() const {
246   return variables_.find("default_constant") != variables_.end();
247 }
248 
GenerateInitSavedDefaultCode(io::Printer * printer) const249 void PrimitiveFieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
250   if (variables_.find("default_constant") != variables_.end()) {
251     printer->Print(variables_,
252       "$default_constant$ = $default_constant_value$;\n");
253   }
254 }
255 
256 void PrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool lazy_init) const257 GenerateMembers(io::Printer* printer, bool lazy_init) const {
258   if (variables_.find("default_constant") != variables_.end()) {
259     // Those primitive types that need a saved default.
260     if (lazy_init) {
261       printer->Print(variables_,
262         "private static $type$ $default_constant$;\n");
263     } else {
264       printer->Print(variables_,
265         "private static final $type$ $default_constant$ =\n"
266         "    $default_constant_value$;\n");
267     }
268   }
269 
270   printer->Print(variables_,
271     "public $type$ $name$;\n");
272 
273   if (params_.generate_has()) {
274     printer->Print(variables_,
275       "public boolean has$capitalized_name$;\n");
276   }
277 }
278 
279 void PrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const280 GenerateClearCode(io::Printer* printer) const {
281   printer->Print(variables_,
282     "$name$ = $default_copy_if_needed$;\n");
283 
284   if (params_.generate_has()) {
285     printer->Print(variables_,
286       "has$capitalized_name$ = false;\n");
287   }
288 }
289 
290 void PrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const291 GenerateMergingCode(io::Printer* printer) const {
292   printer->Print(variables_,
293     "this.$name$ = input.read$capitalized_type$();\n");
294 
295   if (params_.generate_has()) {
296     printer->Print(variables_,
297       "has$capitalized_name$ = true;\n");
298   }
299 }
300 
301 void PrimitiveFieldGenerator::
GenerateSerializationConditional(io::Printer * printer) const302 GenerateSerializationConditional(io::Printer* printer) const {
303   if (params_.use_reference_types_for_primitives()) {
304     // For reference type mode, serialize based on equality
305     // to null.
306     printer->Print(variables_,
307       "if (this.$name$ != null) {\n");
308     return;
309   }
310   if (params_.generate_has()) {
311     printer->Print(variables_,
312       "if (has$capitalized_name$ || ");
313   } else {
314     printer->Print(variables_,
315       "if (");
316   }
317   JavaType java_type = GetJavaType(descriptor_);
318   if (IsArrayType(java_type)) {
319     printer->Print(variables_,
320       "!java.util.Arrays.equals(this.$name$, $default$)) {\n");
321   } else if (IsReferenceType(java_type)) {
322     printer->Print(variables_,
323       "!this.$name$.equals($default$)) {\n");
324   } else if (java_type == JAVATYPE_FLOAT) {
325     printer->Print(variables_,
326       "java.lang.Float.floatToIntBits(this.$name$)\n"
327       "    != java.lang.Float.floatToIntBits($default$)) {\n");
328   } else if (java_type == JAVATYPE_DOUBLE) {
329     printer->Print(variables_,
330       "java.lang.Double.doubleToLongBits(this.$name$)\n"
331       "    != java.lang.Double.doubleToLongBits($default$)) {\n");
332   } else {
333     printer->Print(variables_,
334       "this.$name$ != $default$) {\n");
335   }
336 }
337 
338 void PrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const339 GenerateSerializationCode(io::Printer* printer) const {
340   if (descriptor_->is_required() && !params_.generate_has()) {
341     // Always serialize a required field if we don't have the 'has' signal.
342     printer->Print(variables_,
343       "output.write$capitalized_type$($number$, this.$name$);\n");
344   } else {
345     GenerateSerializationConditional(printer);
346     printer->Print(variables_,
347       "  output.write$capitalized_type$($number$, this.$name$);\n"
348       "}\n");
349   }
350 }
351 
352 void PrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const353 GenerateSerializedSizeCode(io::Printer* printer) const {
354   if (descriptor_->is_required() && !params_.generate_has()) {
355     printer->Print(variables_,
356       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
357       "    .compute$capitalized_type$Size($number$, this.$name$);\n");
358   } else {
359     GenerateSerializationConditional(printer);
360     printer->Print(variables_,
361       "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
362       "      .compute$capitalized_type$Size($number$, this.$name$);\n"
363       "}\n");
364   }
365 }
366 
367 void RepeatedPrimitiveFieldGenerator::
GenerateFixClonedCode(io::Printer * printer) const368 GenerateFixClonedCode(io::Printer* printer) const {
369   printer->Print(variables_,
370     "if (this.$name$ != null && this.$name$.length > 0) {\n"
371     "  cloned.$name$ = this.$name$.clone();\n"
372     "}\n");
373 }
374 
375 void PrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const376 GenerateEqualsCode(io::Printer* printer) const {
377   // We define equality as serialized form equality. If generate_has(),
378   // then if the field value equals the default value in both messages,
379   // but one's 'has' field is set and the other's is not, the serialized
380   // forms are different and we should return false.
381   JavaType java_type = GetJavaType(descriptor_);
382   if (java_type == JAVATYPE_BYTES) {
383     printer->Print(variables_,
384       "if (!java.util.Arrays.equals(this.$name$, other.$name$)");
385     if (params_.generate_has()) {
386       printer->Print(variables_,
387         "\n"
388         "    || (java.util.Arrays.equals(this.$name$, $default$)\n"
389         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
390     }
391     printer->Print(") {\n"
392       "  return false;\n"
393       "}\n");
394   } else if (java_type == JAVATYPE_STRING
395       || params_.use_reference_types_for_primitives()) {
396     printer->Print(variables_,
397       "if (this.$name$ == null) {\n"
398       "  if (other.$name$ != null) {\n"
399       "    return false;\n"
400       "  }\n"
401       "} else if (!this.$name$.equals(other.$name$)");
402     if (params_.generate_has()) {
403       printer->Print(variables_,
404         "\n"
405         "    || (this.$name$.equals($default$)\n"
406         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
407     }
408     printer->Print(") {\n"
409       "  return false;\n"
410       "}\n");
411   } else if (java_type == JAVATYPE_FLOAT) {
412     printer->Print(variables_,
413       "{\n"
414       "  int bits = java.lang.Float.floatToIntBits(this.$name$);\n"
415       "  if (bits != java.lang.Float.floatToIntBits(other.$name$)");
416     if (params_.generate_has()) {
417       printer->Print(variables_,
418         "\n"
419         "      || (bits == java.lang.Float.floatToIntBits($default$)\n"
420         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
421     }
422     printer->Print(") {\n"
423       "    return false;\n"
424       "  }\n"
425       "}\n");
426   } else if (java_type == JAVATYPE_DOUBLE) {
427     printer->Print(variables_,
428       "{\n"
429       "  long bits = java.lang.Double.doubleToLongBits(this.$name$);\n"
430       "  if (bits != java.lang.Double.doubleToLongBits(other.$name$)");
431     if (params_.generate_has()) {
432       printer->Print(variables_,
433         "\n"
434         "      || (bits == java.lang.Double.doubleToLongBits($default$)\n"
435         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
436     }
437     printer->Print(") {\n"
438       "    return false;\n"
439       "  }\n"
440       "}\n");
441   } else {
442     printer->Print(variables_,
443       "if (this.$name$ != other.$name$");
444     if (params_.generate_has()) {
445       printer->Print(variables_,
446         "\n"
447         "    || (this.$name$ == $default$\n"
448         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
449     }
450     printer->Print(") {\n"
451       "  return false;\n"
452       "}\n");
453   }
454 }
455 
456 void PrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const457 GenerateHashCodeCode(io::Printer* printer) const {
458   JavaType java_type = GetJavaType(descriptor_);
459   if (java_type == JAVATYPE_BYTES) {
460     printer->Print(variables_,
461       "result = 31 * result + java.util.Arrays.hashCode(this.$name$);\n");
462   } else if (java_type == JAVATYPE_STRING
463       || params_.use_reference_types_for_primitives()) {
464     printer->Print(variables_,
465       "result = 31 * result\n"
466       "    + (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
467   } else {
468     switch (java_type) {
469       // For all Java primitive types below, the hash codes match the
470       // results of BoxedType.valueOf(primitiveValue).hashCode().
471       case JAVATYPE_INT:
472         printer->Print(variables_,
473           "result = 31 * result + this.$name$;\n");
474         break;
475       case JAVATYPE_LONG:
476         printer->Print(variables_,
477           "result = 31 * result\n"
478           "    + (int) (this.$name$ ^ (this.$name$ >>> 32));\n");
479         break;
480       case JAVATYPE_FLOAT:
481         printer->Print(variables_,
482           "result = 31 * result\n"
483           "    + java.lang.Float.floatToIntBits(this.$name$);\n");
484         break;
485       case JAVATYPE_DOUBLE:
486         printer->Print(variables_,
487           "{\n"
488           "  long v = java.lang.Double.doubleToLongBits(this.$name$);\n"
489           "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
490           "}\n");
491         break;
492       case JAVATYPE_BOOLEAN:
493         printer->Print(variables_,
494           "result = 31 * result + (this.$name$ ? 1231 : 1237);\n");
495         break;
496       default:
497         GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
498         break;
499     }
500   }
501 }
502 
503 // ===================================================================
504 
505 AccessorPrimitiveFieldGenerator::
AccessorPrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params,int has_bit_index)506 AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
507      const Params& params, int has_bit_index)
508   : FieldGenerator(params), descriptor_(descriptor) {
509   SetPrimitiveVariables(descriptor, params, &variables_);
510   SetBitOperationVariables("has", has_bit_index, &variables_);
511 }
512 
~AccessorPrimitiveFieldGenerator()513 AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
514 
SavedDefaultNeeded() const515 bool AccessorPrimitiveFieldGenerator::SavedDefaultNeeded() const {
516   return variables_.find("default_constant") != variables_.end();
517 }
518 
519 void AccessorPrimitiveFieldGenerator::
GenerateInitSavedDefaultCode(io::Printer * printer) const520 GenerateInitSavedDefaultCode(io::Printer* printer) const {
521   if (variables_.find("default_constant") != variables_.end()) {
522     printer->Print(variables_,
523       "$default_constant$ = $default_constant_value$;\n");
524   }
525 }
526 
527 void AccessorPrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool lazy_init) const528 GenerateMembers(io::Printer* printer, bool lazy_init) const {
529   if (variables_.find("default_constant") != variables_.end()) {
530     // Those primitive types that need a saved default.
531     if (lazy_init) {
532       printer->Print(variables_,
533         "private static $type$ $default_constant$;\n");
534     } else {
535       printer->Print(variables_,
536         "private static final $type$ $default_constant$ =\n"
537         "    $default_constant_value$;\n");
538     }
539   }
540   printer->Print(variables_,
541     "private $type$ $name$_;\n"
542     "public $type$ get$capitalized_name$() {\n"
543     "  return $name$_;\n"
544     "}\n"
545     "public $message_name$ set$capitalized_name$($type$ value) {\n");
546   if (IsReferenceType(GetJavaType(descriptor_))) {
547     printer->Print(variables_,
548       "  if (value == null) {\n"
549       "    throw new java.lang.NullPointerException();\n"
550       "  }\n");
551   }
552   printer->Print(variables_,
553     "  $name$_ = value;\n"
554     "  $set_has$;\n"
555     "  return this;\n"
556     "}\n"
557     "public boolean has$capitalized_name$() {\n"
558     "  return $get_has$;\n"
559     "}\n"
560     "public $message_name$ clear$capitalized_name$() {\n"
561     "  $name$_ = $default_copy_if_needed$;\n"
562     "  $clear_has$;\n"
563     "  return this;\n"
564     "}\n");
565 }
566 
567 void AccessorPrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const568 GenerateClearCode(io::Printer* printer) const {
569   printer->Print(variables_,
570     "$name$_ = $default_copy_if_needed$;\n");
571 }
572 
573 void AccessorPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const574 GenerateMergingCode(io::Printer* printer) const {
575   printer->Print(variables_,
576     "$name$_ = input.read$capitalized_type$();\n"
577     "$set_has$;\n");
578 }
579 
580 void AccessorPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const581 GenerateSerializationCode(io::Printer* printer) const {
582   printer->Print(variables_,
583     "if ($get_has$) {\n"
584     "  output.write$capitalized_type$($number$, $name$_);\n"
585     "}\n");
586 }
587 
588 void AccessorPrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const589 GenerateSerializedSizeCode(io::Printer* printer) const {
590   printer->Print(variables_,
591     "if ($get_has$) {\n"
592     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
593     "      .compute$capitalized_type$Size($number$, $name$_);\n"
594     "}\n");
595 }
596 
597 void AccessorPrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const598 GenerateEqualsCode(io::Printer* printer) const {
599   switch (GetJavaType(descriptor_)) {
600     // For all Java primitive types below, the equality checks match the
601     // results of BoxedType.valueOf(primitiveValue).equals(otherValue).
602     case JAVATYPE_FLOAT:
603       printer->Print(variables_,
604         "if ($different_has$\n"
605         "    || java.lang.Float.floatToIntBits($name$_)\n"
606         "        != java.lang.Float.floatToIntBits(other.$name$_)) {\n"
607         "  return false;\n"
608         "}\n");
609       break;
610     case JAVATYPE_DOUBLE:
611       printer->Print(variables_,
612         "if ($different_has$\n"
613         "    || java.lang.Double.doubleToLongBits($name$_)\n"
614         "        != java.lang.Double.doubleToLongBits(other.$name$_)) {\n"
615         "  return false;\n"
616         "}\n");
617       break;
618     case JAVATYPE_INT:
619     case JAVATYPE_LONG:
620     case JAVATYPE_BOOLEAN:
621       printer->Print(variables_,
622         "if ($different_has$\n"
623         "    || $name$_ != other.$name$_) {\n"
624         "  return false;\n"
625         "}\n");
626       break;
627     case JAVATYPE_STRING:
628       // Accessor style would guarantee $name$_ non-null
629       printer->Print(variables_,
630         "if ($different_has$\n"
631         "    || !$name$_.equals(other.$name$_)) {\n"
632         "  return false;\n"
633         "}\n");
634       break;
635     case JAVATYPE_BYTES:
636       // Accessor style would guarantee $name$_ non-null
637       printer->Print(variables_,
638         "if ($different_has$\n"
639         "    || !java.util.Arrays.equals($name$_, other.$name$_)) {\n"
640         "  return false;\n"
641         "}\n");
642       break;
643     default:
644       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
645       break;
646   }
647 }
648 
649 void AccessorPrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const650 GenerateHashCodeCode(io::Printer* printer) const {
651   switch (GetJavaType(descriptor_)) {
652     // For all Java primitive types below, the hash codes match the
653     // results of BoxedType.valueOf(primitiveValue).hashCode().
654     case JAVATYPE_INT:
655       printer->Print(variables_,
656         "result = 31 * result + $name$_;\n");
657       break;
658     case JAVATYPE_LONG:
659       printer->Print(variables_,
660         "result = 31 * result + (int) ($name$_ ^ ($name$_ >>> 32));\n");
661       break;
662     case JAVATYPE_FLOAT:
663       printer->Print(variables_,
664         "result = 31 * result +\n"
665         "    java.lang.Float.floatToIntBits($name$_);\n");
666       break;
667     case JAVATYPE_DOUBLE:
668       printer->Print(variables_,
669         "{\n"
670         "  long v = java.lang.Double.doubleToLongBits($name$_);\n"
671         "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
672         "}\n");
673       break;
674     case JAVATYPE_BOOLEAN:
675       printer->Print(variables_,
676         "result = 31 * result + ($name$_ ? 1231 : 1237);\n");
677       break;
678     case JAVATYPE_STRING:
679       // Accessor style would guarantee $name$_ non-null
680       printer->Print(variables_,
681         "result = 31 * result + $name$_.hashCode();\n");
682       break;
683     case JAVATYPE_BYTES:
684       // Accessor style would guarantee $name$_ non-null
685       printer->Print(variables_,
686         "result = 31 * result + java.util.Arrays.hashCode($name$_);\n");
687       break;
688     default:
689       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
690       break;
691   }
692 }
693 
694 // ===================================================================
695 
PrimitiveOneofFieldGenerator(const FieldDescriptor * descriptor,const Params & params)696 PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
697     const FieldDescriptor* descriptor, const Params& params)
698   : FieldGenerator(params), descriptor_(descriptor) {
699     SetPrimitiveVariables(descriptor, params, &variables_);
700     SetCommonOneofVariables(descriptor, &variables_);
701 }
702 
~PrimitiveOneofFieldGenerator()703 PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
704 
GenerateMembers(io::Printer * printer,bool) const705 void PrimitiveOneofFieldGenerator::GenerateMembers(
706     io::Printer* printer, bool /*unused lazy_init*/) const {
707   printer->Print(variables_,
708     "public boolean has$capitalized_name$() {\n"
709     "  return $has_oneof_case$;\n"
710     "}\n"
711     "public $type$ get$capitalized_name$() {\n"
712     "  if ($has_oneof_case$) {\n"
713     "    return ($type$) ($boxed_type$) this.$oneof_name$_;\n"
714     "  }\n"
715     "  return $default$;\n"
716     "}\n"
717     "public $message_name$ set$capitalized_name$($type$ value) {\n"
718     "  $set_oneof_case$;\n"
719     "  this.$oneof_name$_ = value;\n"
720     "  return this;\n"
721     "}\n");
722 }
723 
GenerateClearCode(io::Printer * printer) const724 void PrimitiveOneofFieldGenerator::GenerateClearCode(
725     io::Printer* printer) const {
726   // No clear method for oneof fields.
727 }
728 
GenerateMergingCode(io::Printer * printer) const729 void PrimitiveOneofFieldGenerator::GenerateMergingCode(
730     io::Printer* printer) const {
731   printer->Print(variables_,
732     "this.$oneof_name$_ = input.read$capitalized_type$();\n"
733     "$set_oneof_case$;\n");
734 }
735 
GenerateSerializationCode(io::Printer * printer) const736 void PrimitiveOneofFieldGenerator::GenerateSerializationCode(
737     io::Printer* printer) const {
738   printer->Print(variables_,
739     "if ($has_oneof_case$) {\n"
740     "  output.write$capitalized_type$(\n"
741     "      $number$, ($boxed_type$) this.$oneof_name$_);\n"
742     "}\n");
743 }
744 
GenerateSerializedSizeCode(io::Printer * printer) const745 void PrimitiveOneofFieldGenerator::GenerateSerializedSizeCode(
746     io::Printer* printer) const {
747   printer->Print(variables_,
748     "if ($has_oneof_case$) {\n"
749     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
750     "      .compute$capitalized_type$Size(\n"
751     "          $number$, ($boxed_type$) this.$oneof_name$_);\n"
752     "}\n");
753 }
754 
GenerateEqualsCode(io::Printer * printer) const755 void PrimitiveOneofFieldGenerator::GenerateEqualsCode(
756     io::Printer* printer) const {
757   GenerateOneofFieldEquals(descriptor_, variables_, printer);
758 }
759 
GenerateHashCodeCode(io::Printer * printer) const760 void PrimitiveOneofFieldGenerator::GenerateHashCodeCode(
761     io::Printer* printer) const {
762   GenerateOneofFieldHashCode(descriptor_, variables_, printer);
763 }
764 
765 // ===================================================================
766 
RepeatedPrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params)767 RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
768     const FieldDescriptor* descriptor, const Params& params)
769   : FieldGenerator(params), descriptor_(descriptor) {
770   SetPrimitiveVariables(descriptor, params, &variables_);
771 }
772 
~RepeatedPrimitiveFieldGenerator()773 RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
774 
775 void RepeatedPrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool) const776 GenerateMembers(io::Printer* printer, bool /*unused init_defaults*/) const {
777   printer->Print(variables_,
778     "public $type$[] $name$;\n");
779 }
780 
781 void RepeatedPrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const782 GenerateClearCode(io::Printer* printer) const {
783   printer->Print(variables_,
784     "$name$ = $default$;\n");
785 }
786 
787 void RepeatedPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const788 GenerateMergingCode(io::Printer* printer) const {
789   // First, figure out the length of the array, then parse.
790   printer->Print(variables_,
791     "int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
792     "    .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
793     "int i = this.$name$ == null ? 0 : this.$name$.length;\n");
794 
795   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
796     printer->Print(variables_,
797       "byte[][] newArray = new byte[i + arrayLength][];\n");
798   } else {
799     printer->Print(variables_,
800       "$type$[] newArray = new $type$[i + arrayLength];\n");
801   }
802   printer->Print(variables_,
803     "if (i != 0) {\n"
804     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
805     "}\n"
806     "for (; i < newArray.length - 1; i++) {\n"
807     "  newArray[i] = input.read$capitalized_type$();\n"
808     "  input.readTag();\n"
809     "}\n"
810     "// Last one without readTag.\n"
811     "newArray[i] = input.read$capitalized_type$();\n"
812     "this.$name$ = newArray;\n");
813 }
814 
815 void RepeatedPrimitiveFieldGenerator::
GenerateMergingCodeFromPacked(io::Printer * printer) const816 GenerateMergingCodeFromPacked(io::Printer* printer) const {
817   printer->Print(
818     "int length = input.readRawVarint32();\n"
819     "int limit = input.pushLimit(length);\n");
820 
821   // If we know the elements will all be of the same size, the arrayLength
822   // can be calculated much more easily. However, FixedSize() returns 1 for
823   // repeated bool fields, which are guaranteed to have the fixed size of
824   // 1 byte per value only if we control the output. On the wire they can
825   // legally appear as variable-size integers, so we need to use the slow
826   // way for repeated bool fields.
827   if (descriptor_->type() == FieldDescriptor::TYPE_BOOL
828       || FixedSize(descriptor_->type()) == -1) {
829     printer->Print(variables_,
830       "// First pass to compute array length.\n"
831       "int arrayLength = 0;\n"
832       "int startPos = input.getPosition();\n"
833       "while (input.getBytesUntilLimit() > 0) {\n"
834       "  input.read$capitalized_type$();\n"
835       "  arrayLength++;\n"
836       "}\n"
837       "input.rewindToPosition(startPos);\n");
838   } else {
839     printer->Print(variables_,
840       "int arrayLength = length / $fixed_size$;\n");
841   }
842 
843   printer->Print(variables_,
844     "int i = this.$name$ == null ? 0 : this.$name$.length;\n"
845     "$type$[] newArray = new $type$[i + arrayLength];\n"
846     "if (i != 0) {\n"
847     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
848     "}\n"
849     "for (; i < newArray.length; i++) {\n"
850     "  newArray[i] = input.read$capitalized_type$();\n"
851     "}\n"
852     "this.$name$ = newArray;\n"
853     "input.popLimit(limit);\n");
854 }
855 
856 void RepeatedPrimitiveFieldGenerator::
GenerateRepeatedDataSizeCode(io::Printer * printer) const857 GenerateRepeatedDataSizeCode(io::Printer* printer) const {
858   // Creates a variable dataSize and puts the serialized size in there.
859   // If the element type is a Java reference type, also generates
860   // dataCount which stores the number of non-null elements in the field.
861   if (IsReferenceType(GetJavaType(descriptor_))) {
862     printer->Print(variables_,
863       "int dataCount = 0;\n"
864       "int dataSize = 0;\n"
865       "for (int i = 0; i < this.$name$.length; i++) {\n"
866       "  $type$ element = this.$name$[i];\n"
867       "  if (element != null) {\n"
868       "    dataCount++;\n"
869       "    dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
870       "        .compute$capitalized_type$SizeNoTag(element);\n"
871       "  }\n"
872       "}\n");
873   } else if (FixedSize(descriptor_->type()) == -1) {
874     printer->Print(variables_,
875       "int dataSize = 0;\n"
876       "for (int i = 0; i < this.$name$.length; i++) {\n"
877       "  $type$ element = this.$name$[i];\n"
878       "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
879       "      .compute$capitalized_type$SizeNoTag(element);\n"
880       "}\n");
881   } else {
882     printer->Print(variables_,
883       "int dataSize = $fixed_size$ * this.$name$.length;\n");
884   }
885 }
886 
887 void RepeatedPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const888 GenerateSerializationCode(io::Printer* printer) const {
889   printer->Print(variables_,
890     "if (this.$name$ != null && this.$name$.length > 0) {\n");
891   printer->Indent();
892 
893   if (descriptor_->is_packable() && descriptor_->options().packed()) {
894     GenerateRepeatedDataSizeCode(printer);
895     printer->Print(variables_,
896       "output.writeRawVarint32($tag$);\n"
897       "output.writeRawVarint32(dataSize);\n"
898       "for (int i = 0; i < this.$name$.length; i++) {\n"
899       "  output.write$capitalized_type$NoTag(this.$name$[i]);\n"
900       "}\n");
901   } else if (IsReferenceType(GetJavaType(descriptor_))) {
902     printer->Print(variables_,
903       "for (int i = 0; i < this.$name$.length; i++) {\n"
904       "  $type$ element = this.$name$[i];\n"
905       "  if (element != null) {\n"
906       "    output.write$capitalized_type$($number$, element);\n"
907       "  }\n"
908       "}\n");
909   } else {
910     printer->Print(variables_,
911       "for (int i = 0; i < this.$name$.length; i++) {\n"
912       "  output.write$capitalized_type$($number$, this.$name$[i]);\n"
913       "}\n");
914   }
915 
916   printer->Outdent();
917   printer->Print("}\n");
918 }
919 
920 void RepeatedPrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const921 GenerateSerializedSizeCode(io::Printer* printer) const {
922   printer->Print(variables_,
923     "if (this.$name$ != null && this.$name$.length > 0) {\n");
924   printer->Indent();
925 
926   GenerateRepeatedDataSizeCode(printer);
927 
928   printer->Print(
929     "size += dataSize;\n");
930   if (descriptor_->is_packable() && descriptor_->options().packed()) {
931     printer->Print(variables_,
932       "size += $tag_size$;\n"
933       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
934       "    .computeRawVarint32Size(dataSize);\n");
935   } else if (IsReferenceType(GetJavaType(descriptor_))) {
936     printer->Print(variables_,
937       "size += $tag_size$ * dataCount;\n");
938   } else {
939     printer->Print(variables_,
940       "size += $tag_size$ * this.$name$.length;\n");
941   }
942 
943   printer->Outdent();
944 
945   printer->Print(
946     "}\n");
947 }
948 
949 void RepeatedPrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const950 GenerateEqualsCode(io::Printer* printer) const {
951   printer->Print(variables_,
952     "if (!com.google.protobuf.nano.InternalNano.equals(\n"
953     "    this.$name$, other.$name$)) {\n"
954     "  return false;\n"
955     "}\n");
956 }
957 
958 void RepeatedPrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const959 GenerateHashCodeCode(io::Printer* printer) const {
960   printer->Print(variables_,
961     "result = 31 * result\n"
962     "    + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
963 }
964 
965 }  // namespace javanano
966 }  // namespace compiler
967 }  // namespace protobuf
968 }  // namespace google
969