• 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 <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   JavaType java_type = GetJavaType(descriptor_);
271   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
272     printer->Print(variables_,
273       "public $type$ $name$Buffer;\n"
274       "public int $name$Offset;\n"
275       "public int $name$Length;\n");
276   } else {
277     printer->Print(variables_,
278       "public $type$ $name$;\n");
279   }
280 
281   if (params_.generate_has()) {
282     printer->Print(variables_,
283       "public boolean has$capitalized_name$;\n");
284   }
285 }
286 
287 void PrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const288 GenerateClearCode(io::Printer* printer) const {
289   JavaType java_type = GetJavaType(descriptor_);
290   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
291     printer->Print(variables_,
292       "$name$Buffer = $default_copy_if_needed$;\n"
293       "$name$Offset = -1;\n"
294       "$name$Length = 0;\n");
295   } else {
296     printer->Print(variables_,
297       "$name$ = $default_copy_if_needed$;\n");
298   }
299 
300   if (params_.generate_has()) {
301     printer->Print(variables_,
302       "has$capitalized_name$ = false;\n");
303   }
304 }
305 
306 void PrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const307 GenerateMergingCode(io::Printer* printer) const {
308   JavaType java_type = GetJavaType(descriptor_);
309   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
310     printer->Print(variables_,
311       "this.$name$Buffer = input.getBuffer();\n"
312       "this.$name$Length = input.readRawVarint32();\n"
313       "this.$name$Offset = input.getAbsolutePosition();\n"
314       "input.skipRawBytes(this.$name$Length);\n");
315   } else {
316     printer->Print(variables_,
317       "this.$name$ = input.read$capitalized_type$();\n");
318   }
319 
320   if (params_.generate_has()) {
321     printer->Print(variables_,
322       "has$capitalized_name$ = true;\n");
323   }
324 }
325 
326 void PrimitiveFieldGenerator::
GenerateSerializationConditional(io::Printer * printer) const327 GenerateSerializationConditional(io::Printer* printer) const {
328   if (params_.use_reference_types_for_primitives()) {
329     // For reference type mode, serialize based on equality
330     // to null.
331     printer->Print(variables_,
332       "if (this.$name$ != null) {\n");
333     return;
334   }
335   if (params_.generate_has()) {
336     printer->Print(variables_,
337       "if (has$capitalized_name$ || ");
338   } else {
339     printer->Print(variables_,
340       "if (");
341   }
342   JavaType java_type = GetJavaType(descriptor_);
343   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
344     printer->Print(variables_,
345       "this.$name$Offset != -1) {\n");
346   } else if (IsArrayType(java_type)) {
347     printer->Print(variables_,
348       "!java.util.Arrays.equals(this.$name$, $default$)) {\n");
349   } else if (IsReferenceType(java_type)) {
350     printer->Print(variables_,
351       "!this.$name$.equals($default$)) {\n");
352   } else if (java_type == JAVATYPE_FLOAT) {
353     printer->Print(variables_,
354       "java.lang.Float.floatToIntBits(this.$name$)\n"
355       "    != java.lang.Float.floatToIntBits($default$)) {\n");
356   } else if (java_type == JAVATYPE_DOUBLE) {
357     printer->Print(variables_,
358       "java.lang.Double.doubleToLongBits(this.$name$)\n"
359       "    != java.lang.Double.doubleToLongBits($default$)) {\n");
360   } else {
361     printer->Print(variables_,
362       "this.$name$ != $default$) {\n");
363   }
364 }
365 
366 void PrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const367 GenerateSerializationCode(io::Printer* printer) const {
368   if (descriptor_->is_required() && !params_.generate_has()) {
369     // Always serialize a required field if we don't have the 'has' signal.
370     GenerateWriteCode(printer);
371   } else {
372     GenerateSerializationConditional(printer);
373     printer->Indent();
374     GenerateWriteCode(printer);
375     printer->Outdent();
376     printer->Print("}\n");
377   }
378 }
379 
380 void PrimitiveFieldGenerator::
GenerateWriteCode(io::Printer * printer) const381 GenerateWriteCode(io::Printer* printer) const {
382   JavaType java_type = GetJavaType(descriptor_);
383   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
384     printer->Print(variables_,
385       "output.write$capitalized_type$($number$, this.$name$Buffer,\n"
386       "    this.$name$Offset, this.$name$Length);\n");
387   } else {
388     printer->Print(variables_,
389       "output.write$capitalized_type$($number$, this.$name$);\n");
390   }
391 }
392 
393 void PrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const394 GenerateSerializedSizeCode(io::Printer* printer) const {
395   if (descriptor_->is_required() && !params_.generate_has()) {
396     GenerateComputeSizeCode(printer);
397   } else {
398     GenerateSerializationConditional(printer);
399     printer->Indent();
400     GenerateComputeSizeCode(printer);
401     printer->Outdent();
402     printer->Print("}\n");
403   }
404 }
405 
406 void PrimitiveFieldGenerator::
GenerateComputeSizeCode(io::Printer * printer) const407 GenerateComputeSizeCode(io::Printer* printer) const {
408   JavaType java_type = GetJavaType(descriptor_);
409   if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
410     printer->Print(variables_,
411       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
412       "    .compute$capitalized_type$Size($number$, this.$name$Length);\n");
413   } else {
414     printer->Print(variables_,
415       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
416       "    .compute$capitalized_type$Size($number$, this.$name$);\n");
417   }
418 }
419 
420 void RepeatedPrimitiveFieldGenerator::
GenerateFixClonedCode(io::Printer * printer) const421 GenerateFixClonedCode(io::Printer* printer) const {
422   printer->Print(variables_,
423     "if (this.$name$ != null && this.$name$.length > 0) {\n"
424     "  cloned.$name$ = this.$name$.clone();\n"
425     "}\n");
426 }
427 
428 void PrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const429 GenerateEqualsCode(io::Printer* printer) const {
430   // We define equality as serialized form equality. If generate_has(),
431   // then if the field value equals the default value in both messages,
432   // but one's 'has' field is set and the other's is not, the serialized
433   // forms are different and we should return false.
434   JavaType java_type = GetJavaType(descriptor_);
435   if (java_type == JAVATYPE_BYTES) {
436     printer->Print(variables_,
437       "if (!java.util.Arrays.equals(this.$name$, other.$name$)");
438     if (params_.generate_has()) {
439       printer->Print(variables_,
440         "\n"
441         "    || (java.util.Arrays.equals(this.$name$, $default$)\n"
442         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
443     }
444     printer->Print(") {\n"
445       "  return false;\n"
446       "}\n");
447   } else if (java_type == JAVATYPE_STRING
448       || params_.use_reference_types_for_primitives()) {
449     printer->Print(variables_,
450       "if (this.$name$ == null) {\n"
451       "  if (other.$name$ != null) {\n"
452       "    return false;\n"
453       "  }\n"
454       "} else if (!this.$name$.equals(other.$name$)");
455     if (params_.generate_has()) {
456       printer->Print(variables_,
457         "\n"
458         "    || (this.$name$.equals($default$)\n"
459         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
460     }
461     printer->Print(") {\n"
462       "  return false;\n"
463       "}\n");
464   } else if (java_type == JAVATYPE_FLOAT) {
465     printer->Print(variables_,
466       "{\n"
467       "  int bits = java.lang.Float.floatToIntBits(this.$name$);\n"
468       "  if (bits != java.lang.Float.floatToIntBits(other.$name$)");
469     if (params_.generate_has()) {
470       printer->Print(variables_,
471         "\n"
472         "      || (bits == java.lang.Float.floatToIntBits($default$)\n"
473         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
474     }
475     printer->Print(") {\n"
476       "    return false;\n"
477       "  }\n"
478       "}\n");
479   } else if (java_type == JAVATYPE_DOUBLE) {
480     printer->Print(variables_,
481       "{\n"
482       "  long bits = java.lang.Double.doubleToLongBits(this.$name$);\n"
483       "  if (bits != java.lang.Double.doubleToLongBits(other.$name$)");
484     if (params_.generate_has()) {
485       printer->Print(variables_,
486         "\n"
487         "      || (bits == java.lang.Double.doubleToLongBits($default$)\n"
488         "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
489     }
490     printer->Print(") {\n"
491       "    return false;\n"
492       "  }\n"
493       "}\n");
494   } else {
495     printer->Print(variables_,
496       "if (this.$name$ != other.$name$");
497     if (params_.generate_has()) {
498       printer->Print(variables_,
499         "\n"
500         "    || (this.$name$ == $default$\n"
501         "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
502     }
503     printer->Print(") {\n"
504       "  return false;\n"
505       "}\n");
506   }
507 }
508 
509 void PrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const510 GenerateHashCodeCode(io::Printer* printer) const {
511   JavaType java_type = GetJavaType(descriptor_);
512   if (java_type == JAVATYPE_BYTES) {
513     printer->Print(variables_,
514       "result = 31 * result + java.util.Arrays.hashCode(this.$name$);\n");
515   } else if (java_type == JAVATYPE_STRING
516       || params_.use_reference_types_for_primitives()) {
517     printer->Print(variables_,
518       "result = 31 * result\n"
519       "    + (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
520   } else {
521     switch (java_type) {
522       // For all Java primitive types below, the hash codes match the
523       // results of BoxedType.valueOf(primitiveValue).hashCode().
524       case JAVATYPE_INT:
525         printer->Print(variables_,
526           "result = 31 * result + this.$name$;\n");
527         break;
528       case JAVATYPE_LONG:
529         printer->Print(variables_,
530           "result = 31 * result\n"
531           "    + (int) (this.$name$ ^ (this.$name$ >>> 32));\n");
532         break;
533       case JAVATYPE_FLOAT:
534         printer->Print(variables_,
535           "result = 31 * result\n"
536           "    + java.lang.Float.floatToIntBits(this.$name$);\n");
537         break;
538       case JAVATYPE_DOUBLE:
539         printer->Print(variables_,
540           "{\n"
541           "  long v = java.lang.Double.doubleToLongBits(this.$name$);\n"
542           "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
543           "}\n");
544         break;
545       case JAVATYPE_BOOLEAN:
546         printer->Print(variables_,
547           "result = 31 * result + (this.$name$ ? 1231 : 1237);\n");
548         break;
549       default:
550         GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
551         break;
552     }
553   }
554 }
555 
556 // ===================================================================
557 
558 AccessorPrimitiveFieldGenerator::
AccessorPrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params,int has_bit_index)559 AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
560      const Params& params, int has_bit_index)
561   : FieldGenerator(params), descriptor_(descriptor) {
562   SetPrimitiveVariables(descriptor, params, &variables_);
563   SetBitOperationVariables("has", has_bit_index, &variables_);
564 }
565 
~AccessorPrimitiveFieldGenerator()566 AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
567 
SavedDefaultNeeded() const568 bool AccessorPrimitiveFieldGenerator::SavedDefaultNeeded() const {
569   return variables_.find("default_constant") != variables_.end();
570 }
571 
572 void AccessorPrimitiveFieldGenerator::
GenerateInitSavedDefaultCode(io::Printer * printer) const573 GenerateInitSavedDefaultCode(io::Printer* printer) const {
574   if (variables_.find("default_constant") != variables_.end()) {
575     printer->Print(variables_,
576       "$default_constant$ = $default_constant_value$;\n");
577   }
578 }
579 
580 void AccessorPrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool lazy_init) const581 GenerateMembers(io::Printer* printer, bool lazy_init) const {
582   if (variables_.find("default_constant") != variables_.end()) {
583     // Those primitive types that need a saved default.
584     if (lazy_init) {
585       printer->Print(variables_,
586         "private static $type$ $default_constant$;\n");
587     } else {
588       printer->Print(variables_,
589         "private static final $type$ $default_constant$ =\n"
590         "    $default_constant_value$;\n");
591     }
592   }
593   printer->Print(variables_,
594     "private $type$ $name$_;\n"
595     "public $type$ get$capitalized_name$() {\n"
596     "  return $name$_;\n"
597     "}\n"
598     "public $message_name$ set$capitalized_name$($type$ value) {\n");
599   if (IsReferenceType(GetJavaType(descriptor_))) {
600     printer->Print(variables_,
601       "  if (value == null) {\n"
602       "    throw new java.lang.NullPointerException();\n"
603       "  }\n");
604   }
605   printer->Print(variables_,
606     "  $name$_ = value;\n"
607     "  $set_has$;\n"
608     "  return this;\n"
609     "}\n"
610     "public boolean has$capitalized_name$() {\n"
611     "  return $get_has$;\n"
612     "}\n"
613     "public $message_name$ clear$capitalized_name$() {\n"
614     "  $name$_ = $default_copy_if_needed$;\n"
615     "  $clear_has$;\n"
616     "  return this;\n"
617     "}\n");
618 }
619 
620 void AccessorPrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const621 GenerateClearCode(io::Printer* printer) const {
622   printer->Print(variables_,
623     "$name$_ = $default_copy_if_needed$;\n");
624 }
625 
626 void AccessorPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const627 GenerateMergingCode(io::Printer* printer) const {
628   printer->Print(variables_,
629     "$name$_ = input.read$capitalized_type$();\n"
630     "$set_has$;\n");
631 }
632 
633 void AccessorPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const634 GenerateSerializationCode(io::Printer* printer) const {
635   printer->Print(variables_,
636     "if ($get_has$) {\n"
637     "  output.write$capitalized_type$($number$, $name$_);\n"
638     "}\n");
639 }
640 
641 void AccessorPrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const642 GenerateSerializedSizeCode(io::Printer* printer) const {
643   printer->Print(variables_,
644     "if ($get_has$) {\n"
645     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
646     "      .compute$capitalized_type$Size($number$, $name$_);\n"
647     "}\n");
648 }
649 
650 void AccessorPrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const651 GenerateEqualsCode(io::Printer* printer) const {
652   switch (GetJavaType(descriptor_)) {
653     // For all Java primitive types below, the equality checks match the
654     // results of BoxedType.valueOf(primitiveValue).equals(otherValue).
655     case JAVATYPE_FLOAT:
656       printer->Print(variables_,
657         "if ($different_has$\n"
658         "    || java.lang.Float.floatToIntBits($name$_)\n"
659         "        != java.lang.Float.floatToIntBits(other.$name$_)) {\n"
660         "  return false;\n"
661         "}\n");
662       break;
663     case JAVATYPE_DOUBLE:
664       printer->Print(variables_,
665         "if ($different_has$\n"
666         "    || java.lang.Double.doubleToLongBits($name$_)\n"
667         "        != java.lang.Double.doubleToLongBits(other.$name$_)) {\n"
668         "  return false;\n"
669         "}\n");
670       break;
671     case JAVATYPE_INT:
672     case JAVATYPE_LONG:
673     case JAVATYPE_BOOLEAN:
674       printer->Print(variables_,
675         "if ($different_has$\n"
676         "    || $name$_ != other.$name$_) {\n"
677         "  return false;\n"
678         "}\n");
679       break;
680     case JAVATYPE_STRING:
681       // Accessor style would guarantee $name$_ non-null
682       printer->Print(variables_,
683         "if ($different_has$\n"
684         "    || !$name$_.equals(other.$name$_)) {\n"
685         "  return false;\n"
686         "}\n");
687       break;
688     case JAVATYPE_BYTES:
689       // Accessor style would guarantee $name$_ non-null
690       printer->Print(variables_,
691         "if ($different_has$\n"
692         "    || !java.util.Arrays.equals($name$_, other.$name$_)) {\n"
693         "  return false;\n"
694         "}\n");
695       break;
696     default:
697       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
698       break;
699   }
700 }
701 
702 void AccessorPrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const703 GenerateHashCodeCode(io::Printer* printer) const {
704   switch (GetJavaType(descriptor_)) {
705     // For all Java primitive types below, the hash codes match the
706     // results of BoxedType.valueOf(primitiveValue).hashCode().
707     case JAVATYPE_INT:
708       printer->Print(variables_,
709         "result = 31 * result + $name$_;\n");
710       break;
711     case JAVATYPE_LONG:
712       printer->Print(variables_,
713         "result = 31 * result + (int) ($name$_ ^ ($name$_ >>> 32));\n");
714       break;
715     case JAVATYPE_FLOAT:
716       printer->Print(variables_,
717         "result = 31 * result +\n"
718         "    java.lang.Float.floatToIntBits($name$_);\n");
719       break;
720     case JAVATYPE_DOUBLE:
721       printer->Print(variables_,
722         "{\n"
723         "  long v = java.lang.Double.doubleToLongBits($name$_);\n"
724         "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
725         "}\n");
726       break;
727     case JAVATYPE_BOOLEAN:
728       printer->Print(variables_,
729         "result = 31 * result + ($name$_ ? 1231 : 1237);\n");
730       break;
731     case JAVATYPE_STRING:
732       // Accessor style would guarantee $name$_ non-null
733       printer->Print(variables_,
734         "result = 31 * result + $name$_.hashCode();\n");
735       break;
736     case JAVATYPE_BYTES:
737       // Accessor style would guarantee $name$_ non-null
738       printer->Print(variables_,
739         "result = 31 * result + java.util.Arrays.hashCode($name$_);\n");
740       break;
741     default:
742       GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
743       break;
744   }
745 }
746 
747 // ===================================================================
748 
PrimitiveOneofFieldGenerator(const FieldDescriptor * descriptor,const Params & params)749 PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
750     const FieldDescriptor* descriptor, const Params& params)
751   : FieldGenerator(params), descriptor_(descriptor) {
752     SetPrimitiveVariables(descriptor, params, &variables_);
753     SetCommonOneofVariables(descriptor, &variables_);
754 }
755 
~PrimitiveOneofFieldGenerator()756 PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
757 
GenerateMembers(io::Printer * printer,bool) const758 void PrimitiveOneofFieldGenerator::GenerateMembers(
759     io::Printer* printer, bool /*unused lazy_init*/) const {
760   printer->Print(variables_,
761     "public boolean has$capitalized_name$() {\n"
762     "  return $has_oneof_case$;\n"
763     "}\n"
764     "public $type$ get$capitalized_name$() {\n"
765     "  if ($has_oneof_case$) {\n"
766     "    return ($type$) ($boxed_type$) this.$oneof_name$_;\n"
767     "  }\n"
768     "  return $default$;\n"
769     "}\n"
770     "public $message_name$ set$capitalized_name$($type$ value) {\n"
771     "  $set_oneof_case$;\n"
772     "  this.$oneof_name$_ = value;\n"
773     "  return this;\n"
774     "}\n");
775 }
776 
GenerateClearCode(io::Printer * printer) const777 void PrimitiveOneofFieldGenerator::GenerateClearCode(
778     io::Printer* printer) const {
779   // No clear method for oneof fields.
780 }
781 
GenerateMergingCode(io::Printer * printer) const782 void PrimitiveOneofFieldGenerator::GenerateMergingCode(
783     io::Printer* printer) const {
784   printer->Print(variables_,
785     "this.$oneof_name$_ = input.read$capitalized_type$();\n"
786     "$set_oneof_case$;\n");
787 }
788 
GenerateSerializationCode(io::Printer * printer) const789 void PrimitiveOneofFieldGenerator::GenerateSerializationCode(
790     io::Printer* printer) const {
791   printer->Print(variables_,
792     "if ($has_oneof_case$) {\n"
793     "  output.write$capitalized_type$(\n"
794     "      $number$, ($boxed_type$) this.$oneof_name$_);\n"
795     "}\n");
796 }
797 
GenerateSerializedSizeCode(io::Printer * printer) const798 void PrimitiveOneofFieldGenerator::GenerateSerializedSizeCode(
799     io::Printer* printer) const {
800   printer->Print(variables_,
801     "if ($has_oneof_case$) {\n"
802     "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
803     "      .compute$capitalized_type$Size(\n"
804     "          $number$, ($boxed_type$) this.$oneof_name$_);\n"
805     "}\n");
806 }
807 
GenerateEqualsCode(io::Printer * printer) const808 void PrimitiveOneofFieldGenerator::GenerateEqualsCode(
809     io::Printer* printer) const {
810   GenerateOneofFieldEquals(descriptor_, variables_, printer);
811 }
812 
GenerateHashCodeCode(io::Printer * printer) const813 void PrimitiveOneofFieldGenerator::GenerateHashCodeCode(
814     io::Printer* printer) const {
815   GenerateOneofFieldHashCode(descriptor_, variables_, printer);
816 }
817 
818 // ===================================================================
819 
RepeatedPrimitiveFieldGenerator(const FieldDescriptor * descriptor,const Params & params)820 RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
821     const FieldDescriptor* descriptor, const Params& params)
822   : FieldGenerator(params), descriptor_(descriptor) {
823   SetPrimitiveVariables(descriptor, params, &variables_);
824 }
825 
~RepeatedPrimitiveFieldGenerator()826 RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
827 
828 void RepeatedPrimitiveFieldGenerator::
GenerateMembers(io::Printer * printer,bool) const829 GenerateMembers(io::Printer* printer, bool /*unused init_defaults*/) const {
830   printer->Print(variables_,
831     "public $type$[] $name$;\n");
832 }
833 
834 void RepeatedPrimitiveFieldGenerator::
GenerateClearCode(io::Printer * printer) const835 GenerateClearCode(io::Printer* printer) const {
836   printer->Print(variables_,
837     "$name$ = $default$;\n");
838 }
839 
840 void RepeatedPrimitiveFieldGenerator::
GenerateMergingCode(io::Printer * printer) const841 GenerateMergingCode(io::Printer* printer) const {
842   // First, figure out the length of the array, then parse.
843   printer->Print(variables_,
844     "int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
845     "    .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
846     "int i = this.$name$ == null ? 0 : this.$name$.length;\n");
847 
848   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
849     printer->Print(variables_,
850       "byte[][] newArray = new byte[i + arrayLength][];\n");
851   } else {
852     printer->Print(variables_,
853       "$type$[] newArray = new $type$[i + arrayLength];\n");
854   }
855   printer->Print(variables_,
856     "if (i != 0) {\n"
857     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
858     "}\n"
859     "for (; i < newArray.length - 1; i++) {\n"
860     "  newArray[i] = input.read$capitalized_type$();\n"
861     "  input.readTag();\n"
862     "}\n"
863     "// Last one without readTag.\n"
864     "newArray[i] = input.read$capitalized_type$();\n"
865     "this.$name$ = newArray;\n");
866 }
867 
868 void RepeatedPrimitiveFieldGenerator::
GenerateMergingCodeFromPacked(io::Printer * printer) const869 GenerateMergingCodeFromPacked(io::Printer* printer) const {
870   printer->Print(
871     "int length = input.readRawVarint32();\n"
872     "int limit = input.pushLimit(length);\n");
873 
874   // If we know the elements will all be of the same size, the arrayLength
875   // can be calculated much more easily. However, FixedSize() returns 1 for
876   // repeated bool fields, which are guaranteed to have the fixed size of
877   // 1 byte per value only if we control the output. On the wire they can
878   // legally appear as variable-size integers, so we need to use the slow
879   // way for repeated bool fields.
880   if (descriptor_->type() == FieldDescriptor::TYPE_BOOL
881       || FixedSize(descriptor_->type()) == -1) {
882     printer->Print(variables_,
883       "// First pass to compute array length.\n"
884       "int arrayLength = 0;\n"
885       "int startPos = input.getPosition();\n"
886       "while (input.getBytesUntilLimit() > 0) {\n"
887       "  input.read$capitalized_type$();\n"
888       "  arrayLength++;\n"
889       "}\n"
890       "input.rewindToPosition(startPos);\n");
891   } else {
892     printer->Print(variables_,
893       "int arrayLength = length / $fixed_size$;\n");
894   }
895 
896   printer->Print(variables_,
897     "int i = this.$name$ == null ? 0 : this.$name$.length;\n"
898     "$type$[] newArray = new $type$[i + arrayLength];\n"
899     "if (i != 0) {\n"
900     "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
901     "}\n"
902     "for (; i < newArray.length; i++) {\n"
903     "  newArray[i] = input.read$capitalized_type$();\n"
904     "}\n"
905     "this.$name$ = newArray;\n"
906     "input.popLimit(limit);\n");
907 }
908 
909 void RepeatedPrimitiveFieldGenerator::
GenerateRepeatedDataSizeCode(io::Printer * printer) const910 GenerateRepeatedDataSizeCode(io::Printer* printer) const {
911   // Creates a variable dataSize and puts the serialized size in there.
912   // If the element type is a Java reference type, also generates
913   // dataCount which stores the number of non-null elements in the field.
914   if (IsReferenceType(GetJavaType(descriptor_))) {
915     printer->Print(variables_,
916       "int dataCount = 0;\n"
917       "int dataSize = 0;\n"
918       "for (int i = 0; i < this.$name$.length; i++) {\n"
919       "  $type$ element = this.$name$[i];\n"
920       "  if (element != null) {\n"
921       "    dataCount++;\n"
922       "    dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
923       "        .compute$capitalized_type$SizeNoTag(element);\n"
924       "  }\n"
925       "}\n");
926   } else if (FixedSize(descriptor_->type()) == -1) {
927     printer->Print(variables_,
928       "int dataSize = 0;\n"
929       "for (int i = 0; i < this.$name$.length; i++) {\n"
930       "  $type$ element = this.$name$[i];\n"
931       "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
932       "      .compute$capitalized_type$SizeNoTag(element);\n"
933       "}\n");
934   } else {
935     printer->Print(variables_,
936       "int dataSize = $fixed_size$ * this.$name$.length;\n");
937   }
938 }
939 
940 void RepeatedPrimitiveFieldGenerator::
GenerateSerializationCode(io::Printer * printer) const941 GenerateSerializationCode(io::Printer* printer) const {
942   printer->Print(variables_,
943     "if (this.$name$ != null && this.$name$.length > 0) {\n");
944   printer->Indent();
945 
946   if (descriptor_->is_packable() && descriptor_->options().packed()) {
947     GenerateRepeatedDataSizeCode(printer);
948     printer->Print(variables_,
949       "output.writeRawVarint32($tag$);\n"
950       "output.writeRawVarint32(dataSize);\n"
951       "for (int i = 0; i < this.$name$.length; i++) {\n"
952       "  output.write$capitalized_type$NoTag(this.$name$[i]);\n"
953       "}\n");
954   } else if (IsReferenceType(GetJavaType(descriptor_))) {
955     printer->Print(variables_,
956       "for (int i = 0; i < this.$name$.length; i++) {\n"
957       "  $type$ element = this.$name$[i];\n"
958       "  if (element != null) {\n"
959       "    output.write$capitalized_type$($number$, element);\n"
960       "  }\n"
961       "}\n");
962   } else {
963     printer->Print(variables_,
964       "for (int i = 0; i < this.$name$.length; i++) {\n"
965       "  output.write$capitalized_type$($number$, this.$name$[i]);\n"
966       "}\n");
967   }
968 
969   printer->Outdent();
970   printer->Print("}\n");
971 }
972 
973 void RepeatedPrimitiveFieldGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const974 GenerateSerializedSizeCode(io::Printer* printer) const {
975   printer->Print(variables_,
976     "if (this.$name$ != null && this.$name$.length > 0) {\n");
977   printer->Indent();
978 
979   GenerateRepeatedDataSizeCode(printer);
980 
981   printer->Print(
982     "size += dataSize;\n");
983   if (descriptor_->is_packable() && descriptor_->options().packed()) {
984     printer->Print(variables_,
985       "size += $tag_size$;\n"
986       "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
987       "    .computeRawVarint32Size(dataSize);\n");
988   } else if (IsReferenceType(GetJavaType(descriptor_))) {
989     printer->Print(variables_,
990       "size += $tag_size$ * dataCount;\n");
991   } else {
992     printer->Print(variables_,
993       "size += $tag_size$ * this.$name$.length;\n");
994   }
995 
996   printer->Outdent();
997 
998   printer->Print(
999     "}\n");
1000 }
1001 
1002 void RepeatedPrimitiveFieldGenerator::
GenerateEqualsCode(io::Printer * printer) const1003 GenerateEqualsCode(io::Printer* printer) const {
1004   printer->Print(variables_,
1005     "if (!com.google.protobuf.nano.InternalNano.equals(\n"
1006     "    this.$name$, other.$name$)) {\n"
1007     "  return false;\n"
1008     "}\n");
1009 }
1010 
1011 void RepeatedPrimitiveFieldGenerator::
GenerateHashCodeCode(io::Printer * printer) const1012 GenerateHashCodeCode(io::Printer* printer) const {
1013   printer->Print(variables_,
1014     "result = 31 * result\n"
1015     "    + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
1016 }
1017 
1018 }  // namespace javanano
1019 }  // namespace compiler
1020 }  // namespace protobuf
1021 }  // namespace google
1022