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 
158 // Return true if the type is a that has variable length
159 // for instance String's.
IsVariableLenType(JavaType type)160 bool IsVariableLenType(JavaType type) {
161   switch (type) {
162     case JAVATYPE_INT    : return false;
163     case JAVATYPE_LONG   : return false;
164     case JAVATYPE_FLOAT  : return false;
165     case JAVATYPE_DOUBLE : return false;
166     case JAVATYPE_BOOLEAN: return false;
167     case JAVATYPE_STRING : return true;
168     case JAVATYPE_BYTES  : return true;
169     case JAVATYPE_ENUM   : return false;
170     case JAVATYPE_MESSAGE: return true;
171 
172     // No default because we want the compiler to complain if any new
173     // JavaTypes are added.
174   }
175 
176   GOOGLE_LOG(FATAL) << "Can't get here.";
177   return false;
178 }
179 
AllAscii(const string & text)180 bool AllAscii(const string& text) {
181   for (int i = 0; i < text.size(); i++) {
182     if ((text[i] & 0x80) != 0) {
183       return false;
184     }
185   }
186   return true;
187 }
188 
SetPrimitiveVariables(const FieldDescriptor * descriptor,const Params params,map<string,string> * variables)189 void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
190                            map<string, string>* variables) {
191   (*variables)["name"] =
192     RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
193   (*variables)["capitalized_name"] =
194     RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
195   (*variables)["number"] = SimpleItoa(descriptor->number());
196   if (params.use_reference_types_for_primitives()
197       && !descriptor->is_repeated()) {
198     (*variables)["type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
199   } else {
200     (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
201   }
202   // Deals with defaults. For C++-string types (string and bytes),
203   // we might need to have the generated code do the unicode decoding
204   // (see comments in InternalNano.java for gory details.). We would
205   // like to do this once into a static field and re-use that from
206   // then on.
207   if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
208       !descriptor->default_value_string().empty() &&
209       !params.use_reference_types_for_primitives()) {
210     if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
211       (*variables)["default"] = DefaultValue(params, descriptor);
212       (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
213       (*variables)["default_constant_value"] = strings::Substitute(
214           "com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
215           CEscape(descriptor->default_value_string()));
216       (*variables)["default_copy_if_needed"] =
217           (*variables)["default"] + ".clone()";
218     } else if (AllAscii(descriptor->default_value_string())) {
219       // All chars are ASCII.  In this case directly referencing a
220       // CEscape()'d string literal works fine.
221       (*variables)["default"] =
222           "\"" + CEscape(descriptor->default_value_string()) + "\"";
223       (*variables)["default_copy_if_needed"] = (*variables)["default"];
224     } else {
225       // Strings where some chars are non-ASCII. We need to save the
226       // default value.
227       (*variables)["default"] = DefaultValue(params, descriptor);
228       (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
229       (*variables)["default_constant_value"] = strings::Substitute(
230           "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
231           CEscape(descriptor->default_value_string()));
232       (*variables)["default_copy_if_needed"] = (*variables)["default"];
233     }
234   } else {
235     // Non-string, non-bytes field. Defaults are literals.
236     (*variables)["default"] = DefaultValue(params, descriptor);
237     (*variables)["default_copy_if_needed"] = (*variables)["default"];
238   }
239   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
240   (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
241   (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
242   (*variables)["tag_size"] = SimpleItoa(
243       WireFormat::TagSize(descriptor->number(), descriptor->type()));
244   (*variables)["non_packed_tag"] = SimpleItoa(
245       internal::WireFormatLite::MakeTag(descriptor->number(),
246           internal::WireFormat::WireTypeForFieldType(descriptor->type())));
247   int fixed_size = FixedSize(descriptor->type());
248   if (fixed_size != -1) {
249     (*variables)["fixed_size"] = SimpleItoa(fixed_size);
250   }
251   (*variables)["message_name"] = descriptor->containing_type()->name();
252   (*variables)["empty_array_name"] = EmptyArrayName(params, descriptor);
253 }
254 }  // namespace
255 
256 // ===================================================================
257 
258 PrimitiveFieldGenerator::
PrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params)259 PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
260   : FieldGenerator(params), descriptor_(descriptor) {
261   SetPrimitiveVariables(descriptor, params, &variables_);
262 }
263 
~PrimitiveFieldGenerator()264 PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
265 
SavedDefaultNeeded() const266 bool PrimitiveFieldGenerator::SavedDefaultNeeded() const {
267   return variables_.find("default_constant") != variables_.end();
268 }
269 
GenerateInitSavedDefaultCode(io::Printer * printer) const270 void PrimitiveFieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
271   if (variables_.find("default_constant") != variables_.end()) {
272     printer->Print(variables_,
273       "$default_constant$ = $default_constant_value$;\n");
274   }
275 }
276 
277 void PrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool lazy_init) const278 GenerateMembers(io::Printer* printer, bool lazy_init) const {
279   if (variables_.find("default_constant") != variables_.end()) {
280     // Those primitive types that need a saved default.
281     if (lazy_init) {
282       printer->Print(variables_,
283         "private static $type$ $default_constant$;\n");
284     } else {
285       printer->Print(variables_,
286         "private static final $type$ $default_constant$ =\n"
287         "    $default_constant_value$;\n");
288     }
289   }
290 
291   JavaType java_type = GetJavaType(descriptor_);
292   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
293     printer->Print(variables_,
294       "public $type$ $name$Buffer;\n"
295       "public int $name$Offset;\n"
296       "public int $name$Length;\n");
297   } else {
298     printer->Print(variables_,
299       "public $type$ $name$;\n");
300   }
301 
302   if (params_.generate_has()) {
303     printer->Print(variables_,
304       "public boolean has$capitalized_name$;\n");
305   }
306 }
307 
308 void PrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const309 GenerateClearCode(io::Printer* printer) const {
310   JavaType java_type = GetJavaType(descriptor_);
311   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
312     printer->Print(variables_,
313       "$name$Buffer = $default_copy_if_needed$;\n"
314       "$name$Offset = -1;\n"
315       "$name$Length = 0;\n");
316   } else {
317     printer->Print(variables_,
318       "$name$ = $default_copy_if_needed$;\n");
319   }
320 
321   if (params_.generate_has()) {
322     printer->Print(variables_,
323       "has$capitalized_name$ = false;\n");
324   }
325 }
326 
327 void PrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const328 GenerateMergingCode(io::Printer* printer) const {
329   JavaType java_type = GetJavaType(descriptor_);
330   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
331     printer->Print(variables_,
332       "this.$name$Buffer = input.getBuffer();\n"
333       "this.$name$Length = input.readRawVarint32();\n"
334       "this.$name$Offset = input.getAbsolutePosition();\n"
335       "input.skipRawBytes(this.$name$Length);\n");
336   } else {
337     printer->Print(variables_,
338       "this.$name$ = input.read$capitalized_type$();\n");
339   }
340 
341   if (params_.generate_has()) {
342     printer->Print(variables_,
343       "has$capitalized_name$ = true;\n");
344   }
345 }
346 
347 void PrimitiveFieldGenerator::
GenerateSerializationConditional(io::Printer * printer) const348 GenerateSerializationConditional(io::Printer* printer) const {
349   if (params_.use_reference_types_for_primitives()) {
350     // For reference type mode, serialize based on equality
351     // to null.
352     printer->Print(variables_,
353       "if (this.$name$ != null) {\n");
354     return;
355   }
356   if (params_.generate_has()) {
357     printer->Print(variables_,
358       "if (has$capitalized_name$ || ");
359   } else {
360     printer->Print(variables_,
361       "if (");
362   }
363   JavaType java_type = GetJavaType(descriptor_);
364   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
365     printer->Print(variables_,
366       "this.$name$Offset != -1) {\n");
367   } else if (IsArrayType(java_type)) {
368     printer->Print(variables_,
369       "!java.util.Arrays.equals(this.$name$, $default$)) {\n");
370   } else if (IsReferenceType(java_type)) {
371     printer->Print(variables_,
372       "!this.$name$.equals($default$)) {\n");
373   } else if (java_type == JAVATYPE_FLOAT) {
374     printer->Print(variables_,
375       "java.lang.Float.floatToIntBits(this.$name$)\n"
376       "    != java.lang.Float.floatToIntBits($default$)) {\n");
377   } else if (java_type == JAVATYPE_DOUBLE) {
378     printer->Print(variables_,
379       "java.lang.Double.doubleToLongBits(this.$name$)\n"
380       "    != java.lang.Double.doubleToLongBits($default$)) {\n");
381   } else {
382     printer->Print(variables_,
383       "this.$name$ != $default$) {\n");
384   }
385 }
386 
387 void PrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const388 GenerateSerializationCode(io::Printer* printer) const {
389   if (descriptor_->is_required() && !params_.generate_has()) {
390     // Always serialize a required field if we don't have the 'has' signal.
391     GenerateWriteCode(printer);
392   } else {
393     GenerateSerializationConditional(printer);
394     printer->Indent();
395     GenerateWriteCode(printer);
396     printer->Outdent();
397     printer->Print("}\n");
398   }
399 }
400 
401 void PrimitiveFieldGenerator::
GenerateWriteCode(io::Printer * printer) const402 GenerateWriteCode(io::Printer* printer) const {
403   JavaType java_type = GetJavaType(descriptor_);
404   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
405     printer->Print(variables_,
406       "output.write$capitalized_type$($number$, this.$name$Buffer,\n"
407       "    this.$name$Offset, this.$name$Length);\n");
408   } else {
409     printer->Print(variables_,
410       "output.write$capitalized_type$($number$, this.$name$);\n");
411   }
412 }
413 
414 void PrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const415 GenerateSerializedSizeCode(io::Printer* printer) const {
416   if (descriptor_->is_required() && !params_.generate_has()) {
417     GenerateComputeSizeCode(printer);
418   } else {
419     GenerateSerializationConditional(printer);
420     printer->Indent();
421     GenerateComputeSizeCode(printer);
422     printer->Outdent();
423     printer->Print("}\n");
424   }
425 }
426 
427 void PrimitiveFieldGenerator::
GenerateComputeSizeCode(io::Printer * printer) const428 GenerateComputeSizeCode(io::Printer* printer) const {
429   JavaType java_type = GetJavaType(descriptor_);
430   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
431     printer->Print(variables_,
432       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
433       "    .compute$capitalized_type$Size($number$, this.$name$Length);\n");
434   } else {
435     printer->Print(variables_,
436       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
437       "    .compute$capitalized_type$Size($number$, this.$name$);\n");
438   }
439 }
440 
441 void RepeatedPrimitiveFieldGenerator::
GenerateFixClonedCode(io::Printer * printer) const442 GenerateFixClonedCode(io::Printer* printer) const {
443   printer->Print(variables_,
444     "if (this.$name$ != null && this.$name$.length > 0) {\n"
445     "  cloned.$name$ = this.$name$.clone();\n"
446     "}\n");
447 }
448 
449 void PrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const450 GenerateEqualsCode(io::Printer* printer) const {
451   // We define equality as serialized form equality. If generate_has(),
452   // then if the field value equals the default value in both messages,
453   // but one's 'has' field is set and the other's is not, the serialized
454   // forms are different and we should return false.
455   JavaType java_type = GetJavaType(descriptor_);
456   if (java_type == JAVATYPE_BYTES) {
457     printer->Print(variables_,
458       "if (!java.util.Arrays.equals(this.$name$, other.$name$)");
459     if (params_.generate_has()) {
460       printer->Print(variables_,
461         "\n"
462         "    || (java.util.Arrays.equals(this.$name$, $default$)\n"
463         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
464     }
465     printer->Print(") {\n"
466       "  return false;\n"
467       "}\n");
468   } else if (java_type == JAVATYPE_STRING
469       || params_.use_reference_types_for_primitives()) {
470     printer->Print(variables_,
471       "if (this.$name$ == null) {\n"
472       "  if (other.$name$ != null) {\n"
473       "    return false;\n"
474       "  }\n"
475       "} else if (!this.$name$.equals(other.$name$)");
476     if (params_.generate_has()) {
477       printer->Print(variables_,
478         "\n"
479         "    || (this.$name$.equals($default$)\n"
480         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
481     }
482     printer->Print(") {\n"
483       "  return false;\n"
484       "}\n");
485   } else if (java_type == JAVATYPE_FLOAT) {
486     printer->Print(variables_,
487       "{\n"
488       "  int bits = java.lang.Float.floatToIntBits(this.$name$);\n"
489       "  if (bits != java.lang.Float.floatToIntBits(other.$name$)");
490     if (params_.generate_has()) {
491       printer->Print(variables_,
492         "\n"
493         "      || (bits == java.lang.Float.floatToIntBits($default$)\n"
494         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
495     }
496     printer->Print(") {\n"
497       "    return false;\n"
498       "  }\n"
499       "}\n");
500   } else if (java_type == JAVATYPE_DOUBLE) {
501     printer->Print(variables_,
502       "{\n"
503       "  long bits = java.lang.Double.doubleToLongBits(this.$name$);\n"
504       "  if (bits != java.lang.Double.doubleToLongBits(other.$name$)");
505     if (params_.generate_has()) {
506       printer->Print(variables_,
507         "\n"
508         "      || (bits == java.lang.Double.doubleToLongBits($default$)\n"
509         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
510     }
511     printer->Print(") {\n"
512       "    return false;\n"
513       "  }\n"
514       "}\n");
515   } else {
516     printer->Print(variables_,
517       "if (this.$name$ != other.$name$");
518     if (params_.generate_has()) {
519       printer->Print(variables_,
520         "\n"
521         "    || (this.$name$ == $default$\n"
522         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
523     }
524     printer->Print(") {\n"
525       "  return false;\n"
526       "}\n");
527   }
528 }
529 
530 void PrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const531 GenerateHashCodeCode(io::Printer* printer) const {
532   JavaType java_type = GetJavaType(descriptor_);
533   if (java_type == JAVATYPE_BYTES) {
534     printer->Print(variables_,
535       "result = 31 * result + java.util.Arrays.hashCode(this.$name$);\n");
536   } else if (java_type == JAVATYPE_STRING
537       || params_.use_reference_types_for_primitives()) {
538     printer->Print(variables_,
539       "result = 31 * result\n"
540       "    + (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
541   } else {
542     switch (java_type) {
543       // For all Java primitive types below, the hash codes match the
544       // results of BoxedType.valueOf(primitiveValue).hashCode().
545       case JAVATYPE_INT:
546         printer->Print(variables_,
547           "result = 31 * result + this.$name$;\n");
548         break;
549       case JAVATYPE_LONG:
550         printer->Print(variables_,
551           "result = 31 * result\n"
552           "    + (int) (this.$name$ ^ (this.$name$ >>> 32));\n");
553         break;
554       case JAVATYPE_FLOAT:
555         printer->Print(variables_,
556           "result = 31 * result\n"
557           "    + java.lang.Float.floatToIntBits(this.$name$);\n");
558         break;
559       case JAVATYPE_DOUBLE:
560         printer->Print(variables_,
561           "{\n"
562           "  long v = java.lang.Double.doubleToLongBits(this.$name$);\n"
563           "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
564           "}\n");
565         break;
566       case JAVATYPE_BOOLEAN:
567         printer->Print(variables_,
568           "result = 31 * result + (this.$name$ ? 1231 : 1237);\n");
569         break;
570       default:
571         GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
572         break;
573     }
574   }
575 }
576 
577 // ===================================================================
578 
579 AccessorPrimitiveFieldGenerator::
AccessorPrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params,int has_bit_index)580 AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
581      const Params& params, int has_bit_index)
582   : FieldGenerator(params), descriptor_(descriptor) {
583   SetPrimitiveVariables(descriptor, params, &variables_);
584   SetBitOperationVariables("has", has_bit_index, &variables_);
585 }
586 
~AccessorPrimitiveFieldGenerator()587 AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
588 
SavedDefaultNeeded() const589 bool AccessorPrimitiveFieldGenerator::SavedDefaultNeeded() const {
590   return variables_.find("default_constant") != variables_.end();
591 }
592 
593 void AccessorPrimitiveFieldGenerator::
GenerateInitSavedDefaultCode(io::Printer * printer) const594 GenerateInitSavedDefaultCode(io::Printer* printer) const {
595   if (variables_.find("default_constant") != variables_.end()) {
596     printer->Print(variables_,
597       "$default_constant$ = $default_constant_value$;\n");
598   }
599 }
600 
601 void AccessorPrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool lazy_init) const602 GenerateMembers(io::Printer* printer, bool lazy_init) const {
603   if (variables_.find("default_constant") != variables_.end()) {
604     // Those primitive types that need a saved default.
605     if (lazy_init) {
606       printer->Print(variables_,
607         "private static $type$ $default_constant$;\n");
608     } else {
609       printer->Print(variables_,
610         "private static final $type$ $default_constant$ =\n"
611         "    $default_constant_value$;\n");
612     }
613   }
614   printer->Print(variables_,
615     "private $type$ $name$_;\n"
616     "public $type$ get$capitalized_name$() {\n"
617     "  return $name$_;\n"
618     "}\n"
619     "public $message_name$ set$capitalized_name$($type$ value) {\n");
620   if (IsReferenceType(GetJavaType(descriptor_))) {
621     printer->Print(variables_,
622       "  if (value == null) {\n"
623       "    throw new java.lang.NullPointerException();\n"
624       "  }\n");
625   }
626   printer->Print(variables_,
627     "  $name$_ = value;\n"
628     "  $set_has$;\n"
629     "  return this;\n"
630     "}\n"
631     "public boolean has$capitalized_name$() {\n"
632     "  return $get_has$;\n"
633     "}\n"
634     "public $message_name$ clear$capitalized_name$() {\n"
635     "  $name$_ = $default_copy_if_needed$;\n"
636     "  $clear_has$;\n"
637     "  return this;\n"
638     "}\n");
639 }
640 
641 void AccessorPrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const642 GenerateClearCode(io::Printer* printer) const {
643 
644   printer->Print(variables_,
645     "$name$_ = $default_copy_if_needed$;\n");
646 }
647 
648 void AccessorPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const649 GenerateMergingCode(io::Printer* printer) const {
650   printer->Print(variables_,
651     "$name$_ = input.read$capitalized_type$();\n"
652     "$set_has$;\n");
653 }
654 
655 void AccessorPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const656 GenerateSerializationCode(io::Printer* printer) const {
657   printer->Print(variables_,
658     "if ($get_has$) {\n"
659     "  output.write$capitalized_type$($number$, $name$_);\n"
660     "}\n");
661 }
662 
663 void AccessorPrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const664 GenerateSerializedSizeCode(io::Printer* printer) const {
665   printer->Print(variables_,
666     "if ($get_has$) {\n"
667     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
668     "      .compute$capitalized_type$Size($number$, $name$_);\n"
669     "}\n");
670 }
671 
672 void AccessorPrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const673 GenerateEqualsCode(io::Printer* printer) const {
674   switch (GetJavaType(descriptor_)) {
675     // For all Java primitive types below, the equality checks match the
676     // results of BoxedType.valueOf(primitiveValue).equals(otherValue).
677     case JAVATYPE_FLOAT:
678       printer->Print(variables_,
679         "if ($different_has$\n"
680         "    || java.lang.Float.floatToIntBits($name$_)\n"
681         "        != java.lang.Float.floatToIntBits(other.$name$_)) {\n"
682         "  return false;\n"
683         "}\n");
684       break;
685     case JAVATYPE_DOUBLE:
686       printer->Print(variables_,
687         "if ($different_has$\n"
688         "    || java.lang.Double.doubleToLongBits($name$_)\n"
689         "        != java.lang.Double.doubleToLongBits(other.$name$_)) {\n"
690         "  return false;\n"
691         "}\n");
692       break;
693     case JAVATYPE_INT:
694     case JAVATYPE_LONG:
695     case JAVATYPE_BOOLEAN:
696       printer->Print(variables_,
697         "if ($different_has$\n"
698         "    || $name$_ != other.$name$_) {\n"
699         "  return false;\n"
700         "}\n");
701       break;
702     case JAVATYPE_STRING:
703       // Accessor style would guarantee $name$_ non-null
704       printer->Print(variables_,
705         "if ($different_has$\n"
706         "    || !$name$_.equals(other.$name$_)) {\n"
707         "  return false;\n"
708         "}\n");
709       break;
710     case JAVATYPE_BYTES:
711       // Accessor style would guarantee $name$_ non-null
712       printer->Print(variables_,
713         "if ($different_has$\n"
714         "    || !java.util.Arrays.equals($name$_, other.$name$_)) {\n"
715         "  return false;\n"
716         "}\n");
717       break;
718     default:
719       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
720       break;
721   }
722 }
723 
724 void AccessorPrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const725 GenerateHashCodeCode(io::Printer* printer) const {
726   switch (GetJavaType(descriptor_)) {
727     // For all Java primitive types below, the hash codes match the
728     // results of BoxedType.valueOf(primitiveValue).hashCode().
729     case JAVATYPE_INT:
730       printer->Print(variables_,
731         "result = 31 * result + $name$_;\n");
732       break;
733     case JAVATYPE_LONG:
734       printer->Print(variables_,
735         "result = 31 * result + (int) ($name$_ ^ ($name$_ >>> 32));\n");
736       break;
737     case JAVATYPE_FLOAT:
738       printer->Print(variables_,
739         "result = 31 * result +\n"
740         "    java.lang.Float.floatToIntBits($name$_);\n");
741       break;
742     case JAVATYPE_DOUBLE:
743       printer->Print(variables_,
744         "{\n"
745         "  long v = java.lang.Double.doubleToLongBits($name$_);\n"
746         "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
747         "}\n");
748       break;
749     case JAVATYPE_BOOLEAN:
750       printer->Print(variables_,
751         "result = 31 * result + ($name$_ ? 1231 : 1237);\n");
752       break;
753     case JAVATYPE_STRING:
754       // Accessor style would guarantee $name$_ non-null
755       printer->Print(variables_,
756         "result = 31 * result + $name$_.hashCode();\n");
757       break;
758     case JAVATYPE_BYTES:
759       // Accessor style would guarantee $name$_ non-null
760       printer->Print(variables_,
761         "result = 31 * result + java.util.Arrays.hashCode($name$_);\n");
762       break;
763     default:
764       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
765       break;
766   }
767 }
768 
769 // ===================================================================
770 
771 RepeatedPrimitiveFieldGenerator::
RepeatedPrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params)772 RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
773   : FieldGenerator(params), descriptor_(descriptor) {
774   SetPrimitiveVariables(descriptor, params, &variables_);
775 }
776 
~RepeatedPrimitiveFieldGenerator()777 RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
778 
779 void RepeatedPrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool) const780 GenerateMembers(io::Printer* printer, bool /*unused init_defaults*/) const {
781   printer->Print(variables_,
782     "public $type$[] $name$;\n");
783 }
784 
785 void RepeatedPrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const786 GenerateClearCode(io::Printer* printer) const {
787   printer->Print(variables_,
788     "$name$ = $default$;\n");
789 }
790 
791 void RepeatedPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const792 GenerateMergingCode(io::Printer* printer) const {
793   // First, figure out the length of the array, then parse.
794   printer->Print(variables_,
795     "int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
796     "    .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
797     "int i = this.$name$ == null ? 0 : this.$name$.length;\n");
798 
799   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
800     printer->Print(variables_,
801       "byte[][] newArray = new byte[i + arrayLength][];\n");
802   } else {
803     printer->Print(variables_,
804       "$type$[] newArray = new $type$[i + arrayLength];\n");
805   }
806   printer->Print(variables_,
807     "if (i != 0) {\n"
808     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
809     "}\n"
810     "for (; i < newArray.length - 1; i++) {\n"
811     "  newArray[i] = input.read$capitalized_type$();\n"
812     "  input.readTag();\n"
813     "}\n"
814     "// Last one without readTag.\n"
815     "newArray[i] = input.read$capitalized_type$();\n"
816     "this.$name$ = newArray;\n");
817 }
818 
819 void RepeatedPrimitiveFieldGenerator::
GenerateMergingCodeFromPacked(io::Printer * printer) const820 GenerateMergingCodeFromPacked(io::Printer* printer) const {
821   printer->Print(
822     "int length = input.readRawVarint32();\n"
823     "int limit = input.pushLimit(length);\n");
824 
825   // If we know the elements will all be of the same size, the arrayLength
826   // can be calculated much more easily. However, FixedSize() returns 1 for
827   // repeated bool fields, which are guaranteed to have the fixed size of
828   // 1 byte per value only if we control the output. On the wire they can
829   // legally appear as variable-size integers, so we need to use the slow
830   // way for repeated bool fields.
831   if (descriptor_->type() == FieldDescriptor::TYPE_BOOL
832       || FixedSize(descriptor_->type()) == -1) {
833     printer->Print(variables_,
834       "// First pass to compute array length.\n"
835       "int arrayLength = 0;\n"
836       "int startPos = input.getPosition();\n"
837       "while (input.getBytesUntilLimit() > 0) {\n"
838       "  input.read$capitalized_type$();\n"
839       "  arrayLength++;\n"
840       "}\n"
841       "input.rewindToPosition(startPos);\n");
842   } else {
843     printer->Print(variables_,
844       "int arrayLength = length / $fixed_size$;\n");
845   }
846 
847   printer->Print(variables_,
848     "int i = this.$name$ == null ? 0 : this.$name$.length;\n"
849     "$type$[] newArray = new $type$[i + arrayLength];\n"
850     "if (i != 0) {\n"
851     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
852     "}\n"
853     "for (; i < newArray.length; i++) {\n"
854     "  newArray[i] = input.read$capitalized_type$();\n"
855     "}\n"
856     "this.$name$ = newArray;\n"
857     "input.popLimit(limit);\n");
858 }
859 
860 void RepeatedPrimitiveFieldGenerator::
GenerateRepeatedDataSizeCode(io::Printer * printer) const861 GenerateRepeatedDataSizeCode(io::Printer* printer) const {
862   // Creates a variable dataSize and puts the serialized size in there.
863   // If the element type is a Java reference type, also generates
864   // dataCount which stores the number of non-null elements in the field.
865   if (IsReferenceType(GetJavaType(descriptor_))) {
866     printer->Print(variables_,
867       "int dataCount = 0;\n"
868       "int dataSize = 0;\n"
869       "for (int i = 0; i < this.$name$.length; i++) {\n"
870       "  $type$ element = this.$name$[i];\n"
871       "  if (element != null) {\n"
872       "    dataCount++;\n"
873       "    dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
874       "        .compute$capitalized_type$SizeNoTag(element);\n"
875       "  }\n"
876       "}\n");
877   } else if (FixedSize(descriptor_->type()) == -1) {
878     printer->Print(variables_,
879       "int dataSize = 0;\n"
880       "for (int i = 0; i < this.$name$.length; i++) {\n"
881       "  $type$ element = this.$name$[i];\n"
882       "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
883       "      .compute$capitalized_type$SizeNoTag(element);\n"
884       "}\n");
885   } else {
886     printer->Print(variables_,
887       "int dataSize = $fixed_size$ * this.$name$.length;\n");
888   }
889 }
890 
891 void RepeatedPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const892 GenerateSerializationCode(io::Printer* printer) const {
893   printer->Print(variables_,
894     "if (this.$name$ != null && this.$name$.length > 0) {\n");
895   printer->Indent();
896 
897   if (descriptor_->is_packable() && descriptor_->options().packed()) {
898     GenerateRepeatedDataSizeCode(printer);
899     printer->Print(variables_,
900       "output.writeRawVarint32($tag$);\n"
901       "output.writeRawVarint32(dataSize);\n"
902       "for (int i = 0; i < this.$name$.length; i++) {\n"
903       "  output.write$capitalized_type$NoTag(this.$name$[i]);\n"
904       "}\n");
905   } else if (IsReferenceType(GetJavaType(descriptor_))) {
906     printer->Print(variables_,
907       "for (int i = 0; i < this.$name$.length; i++) {\n"
908       "  $type$ element = this.$name$[i];\n"
909       "  if (element != null) {\n"
910       "    output.write$capitalized_type$($number$, element);\n"
911       "  }\n"
912       "}\n");
913   } else {
914     printer->Print(variables_,
915       "for (int i = 0; i < this.$name$.length; i++) {\n"
916       "  output.write$capitalized_type$($number$, this.$name$[i]);\n"
917       "}\n");
918   }
919 
920   printer->Outdent();
921   printer->Print("}\n");
922 }
923 
924 void RepeatedPrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const925 GenerateSerializedSizeCode(io::Printer* printer) const {
926   printer->Print(variables_,
927     "if (this.$name$ != null && this.$name$.length > 0) {\n");
928   printer->Indent();
929 
930   GenerateRepeatedDataSizeCode(printer);
931 
932   printer->Print(
933     "size += dataSize;\n");
934   if (descriptor_->is_packable() && descriptor_->options().packed()) {
935     printer->Print(variables_,
936       "size += $tag_size$;\n"
937       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
938       "    .computeRawVarint32Size(dataSize);\n");
939   } else if (IsReferenceType(GetJavaType(descriptor_))) {
940     printer->Print(variables_,
941       "size += $tag_size$ * dataCount;\n");
942   } else {
943     printer->Print(variables_,
944       "size += $tag_size$ * this.$name$.length;\n");
945   }
946 
947   printer->Outdent();
948 
949   printer->Print(
950     "}\n");
951 }
952 
953 void RepeatedPrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const954 GenerateEqualsCode(io::Printer* printer) const {
955   printer->Print(variables_,
956     "if (!com.google.protobuf.nano.InternalNano.equals(\n"
957     "    this.$name$, other.$name$)) {\n"
958     "  return false;\n"
959     "}\n");
960 }
961 
962 void RepeatedPrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const963 GenerateHashCodeCode(io::Printer* printer) const {
964   printer->Print(variables_,
965     "result = 31 * result\n"
966     "    + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
967 }
968 
969 }  // namespace javanano
970 }  // namespace compiler
971 }  // namespace protobuf
972 }  // namespace google
973