javanano_primitive_field.cc revision 5dca493053aa93bdd2b5dba842ad87d34ba31521
19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Protocol Buffers - Google's data interchange format
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Copyright 2008 Google Inc.  All rights reserved.
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// http://code.google.com/p/protobuf/
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Redistribution and use in source and binary forms, with or without
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// modification, are permitted provided that the following conditions are
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// met:
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//     * Redistributions of source code must retain the above copyright
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// notice, this list of conditions and the following disclaimer.
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//     * Redistributions in binary form must reproduce the above
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// copyright notice, this list of conditions and the following disclaimer
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// in the documentation and/or other materials provided with the
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// distribution.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//     * Neither the name of Google Inc. nor the names of its
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// contributors may be used to endorse or promote products derived from
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// this software without specific prior written permission.
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Author: kenton@google.com (Kenton Varda)
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//  Based on original Protocol Buffers design by
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson//  Sanjay Ghemawat, Jeff Dean, and others.
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <map>
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <math.h>
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <string>
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <google/protobuf/stubs/common.h>
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <google/protobuf/compiler/javanano/javanano_helpers.h>
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <google/protobuf/io/printer.h>
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <google/protobuf/wire_format.h>
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <google/protobuf/stubs/strutil.h>
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson#include <google/protobuf/stubs/substitute.h>
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonnamespace google {
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonnamespace protobuf {
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonnamespace compiler {
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonnamespace javanano {
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonusing internal::WireFormat;
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonusing internal::WireFormatLite;
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonnamespace {
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonconst char* PrimitiveTypeName(JavaType type) {
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (type) {
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_INT    : return "int";
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_LONG   : return "long";
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_FLOAT  : return "float";
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_DOUBLE : return "double";
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BOOLEAN: return "boolean";
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_STRING : return "java.lang.String";
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BYTES  : return "byte[]";
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_ENUM   : return NULL;
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_MESSAGE: return NULL;
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // No default because we want the compiler to complain if any new
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // JavaTypes are added.
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  GOOGLE_LOG(FATAL) << "Can't get here.";
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return NULL;
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool IsReferenceType(JavaType type) {
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (type) {
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_INT    : return false;
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_LONG   : return false;
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_FLOAT  : return false;
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_DOUBLE : return false;
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BOOLEAN: return false;
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_STRING : return true;
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BYTES  : return true;
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_ENUM   : return false;
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_MESSAGE: return true;
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // No default because we want the compiler to complain if any new
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // JavaTypes are added.
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  GOOGLE_LOG(FATAL) << "Can't get here.";
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool IsArrayType(JavaType type) {
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (type) {
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_INT    : return false;
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_LONG   : return false;
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_FLOAT  : return false;
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_DOUBLE : return false;
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BOOLEAN: return false;
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_STRING : return false;
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BYTES  : return true;
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_ENUM   : return false;
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_MESSAGE: return false;
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // No default because we want the compiler to complain if any new
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // JavaTypes are added.
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  GOOGLE_LOG(FATAL) << "Can't get here.";
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonconst char* GetCapitalizedType(const FieldDescriptor* field) {
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (field->type()) {
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_INT32   : return "Int32"   ;
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_UINT32  : return "UInt32"  ;
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SINT32  : return "SInt32"  ;
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_INT64   : return "Int64"   ;
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_UINT64  : return "UInt64"  ;
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SINT64  : return "SInt64"  ;
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FLOAT   : return "Float"   ;
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_DOUBLE  : return "Double"  ;
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_BOOL    : return "Bool"    ;
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_STRING  : return "String"  ;
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_BYTES   : return "Bytes"   ;
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_ENUM    : return "Enum"    ;
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_GROUP   : return "Group"   ;
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // No default because we want the compiler to complain if any new
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // types are added.
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  GOOGLE_LOG(FATAL) << "Can't get here.";
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return NULL;
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// For encodings with fixed sizes, returns that size in bytes.  Otherwise
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// returns -1.
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonint FixedSize(FieldDescriptor::Type type) {
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (type) {
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_INT32   : return -1;
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_INT64   : return -1;
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_UINT32  : return -1;
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_UINT64  : return -1;
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SINT32  : return -1;
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SINT64  : return -1;
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_ENUM    : return -1;
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_STRING  : return -1;
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_BYTES   : return -1;
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_GROUP   : return -1;
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_MESSAGE : return -1;
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // No default because we want the compiler to complain if any new
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // types are added.
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  GOOGLE_LOG(FATAL) << "Can't get here.";
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return -1;
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Returns true if the field has a default value equal to NaN.
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool IsDefaultNaN(const FieldDescriptor* field) {
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (field->type()) {
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_INT32   : return false;
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_UINT32  : return false;
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SINT32  : return false;
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FIXED32 : return false;
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SFIXED32: return false;
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_INT64   : return false;
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_UINT64  : return false;
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SINT64  : return false;
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FIXED64 : return false;
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_SFIXED64: return false;
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_FLOAT   :
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return isnan(field->default_value_float());
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_DOUBLE  :
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return isnan(field->default_value_double());
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_BOOL    : return false;
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_STRING  : return false;
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_BYTES   : return false;
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_ENUM    : return false;
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_GROUP   : return false;
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case FieldDescriptor::TYPE_MESSAGE : return false;
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // No default because we want the compiler to complain if any new
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // types are added.
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  GOOGLE_LOG(FATAL) << "Can't get here.";
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// Return true if the type is a that has variable length
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// for instance String's.
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool IsVariableLenType(JavaType type) {
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  switch (type) {
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_INT    : return false;
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_LONG   : return false;
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_FLOAT  : return false;
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_DOUBLE : return false;
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BOOLEAN: return false;
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_STRING : return true;
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_BYTES  : return true;
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_ENUM   : return false;
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case JAVATYPE_MESSAGE: return true;
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // No default because we want the compiler to complain if any new
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // JavaTypes are added.
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  GOOGLE_LOG(FATAL) << "Can't get here.";
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return false;
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonbool AllAscii(const string& text) {
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  for (int i = 0; i < text.size(); i++) {
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if ((text[i] & 0x80) != 0) {
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  return true;
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonvoid SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                           map<string, string>* variables) {
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["name"] =
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["capitalized_name"] =
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["number"] = SimpleItoa(descriptor->number());
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["default"] = DefaultValue(params, descriptor);
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // For C++-string types (string and bytes), we might need to have
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // the generated code do the unicode decoding (see comments in
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // InternalNano.java for gory details.). We would like to do this
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // once into a "private static final" field and re-use that from
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // then on.
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      !descriptor->default_value_string().empty()) {
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    string default_value;
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default_value = strings::Substitute(
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          "com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          CEscape(descriptor->default_value_string()));
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (*variables)["default_copy_if_needed"] = (*variables)["default"] + ".clone()";
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    } else {
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (AllAscii(descriptor->default_value_string())) {
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // All chars are ASCII.  In this case CEscape() works fine.
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        default_value = "\"" + CEscape(descriptor->default_value_string()) + "\"";
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      } else {
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        default_value = strings::Substitute(
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            CEscape(descriptor->default_value_string()));
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (*variables)["default_copy_if_needed"] = (*variables)["default"];
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    (*variables)["default_constant_value"] = default_value;
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else {
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    (*variables)["default_copy_if_needed"] = (*variables)["default"];
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["tag_size"] = SimpleItoa(
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      WireFormat::TagSize(descriptor->number(), descriptor->type()));
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  int fixed_size = FixedSize(descriptor->type());
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (fixed_size != -1) {
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["message_name"] = descriptor->containing_type()->name();
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  (*variables)["empty_array_name"] = EmptyArrayName(params, descriptor);
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}  // namespace
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// ===================================================================
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonPrimitiveFieldGenerator::
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  : FieldGenerator(params), descriptor_(descriptor) {
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  SetPrimitiveVariables(descriptor, params, &variables_);
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonPrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonvoid PrimitiveFieldGenerator::
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonGenerateMembers(io::Printer* printer) const {
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (variables_.find("default_constant_value") != variables_.end()) {
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Those primitive types that need a saved default.
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "private static final $type$ $default_constant$ = $default_constant_value$;\n");
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  printer->Print(variables_,
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    "public $type$ $name$ = $default_copy_if_needed$;\n");
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (params_.generate_has()) {
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "public boolean has$capitalized_name$ = false;\n");
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonvoid PrimitiveFieldGenerator::
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonGenerateClearCode(io::Printer* printer) const {
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  printer->Print(variables_,
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    "$name$ = $default_copy_if_needed$;\n");
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (params_.generate_has()) {
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "has$capitalized_name$ = false;\n");
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonvoid PrimitiveFieldGenerator::
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonGenerateMergingCode(io::Printer* printer) const {
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  printer->Print(variables_,
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    "this.$name$ = input.read$capitalized_type$();\n");
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (params_.generate_has()) {
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "has$capitalized_name$ = true;\n");
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonvoid PrimitiveFieldGenerator::
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonGenerateSerializationConditional(io::Printer* printer) const {
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (params_.generate_has()) {
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "if (has$capitalized_name$ || ");
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else {
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "if (");
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (IsArrayType(GetJavaType(descriptor_))) {
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "!java.util.Arrays.equals(this.$name$, $default$)) {\n");
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else if (IsReferenceType(GetJavaType(descriptor_))) {
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "!this.$name$.equals($default$)) {\n");
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else if (IsDefaultNaN(descriptor_)) {
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "!$capitalized_type$.isNaN(this.$name$)) {\n");
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else {
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "this.$name$ != $default$) {\n");
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonvoid PrimitiveFieldGenerator::
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonGenerateSerializationCode(io::Printer* printer) const {
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (descriptor_->is_required()) {
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "output.write$capitalized_type$($number$, this.$name$);\n");
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else {
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    GenerateSerializationConditional(printer);
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "  output.write$capitalized_type$($number$, this.$name$);\n"
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "}\n");
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonvoid PrimitiveFieldGenerator::
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse WilsonGenerateSerializedSizeCode(io::Printer* printer) const {
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  if (descriptor_->is_required()) {
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "    .compute$capitalized_type$Size($number$, this.$name$);\n");
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  } else {
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    GenerateSerializationConditional(printer);
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    printer->Print(variables_,
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "      .compute$capitalized_type$Size($number$, this.$name$);\n"
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      "}\n");
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
392
393string PrimitiveFieldGenerator::GetBoxedType() const {
394  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
395}
396
397// ===================================================================
398
399AccessorPrimitiveFieldGenerator::
400AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
401     const Params& params, int has_bit_index)
402  : FieldGenerator(params), descriptor_(descriptor) {
403  SetPrimitiveVariables(descriptor, params, &variables_);
404  SetBitOperationVariables("has", has_bit_index, &variables_);
405}
406
407AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
408
409void AccessorPrimitiveFieldGenerator::
410GenerateMembers(io::Printer* printer) const {
411  if (variables_.find("default_constant_value") != variables_.end()) {
412    printer->Print(variables_,
413      "private static final $type$ $default_constant$ = $default_constant_value$;\n");
414  }
415  printer->Print(variables_,
416    "private $type$ $name$_ = $default_copy_if_needed$;\n"
417    "public $type$ get$capitalized_name$() {\n"
418    "  return $name$_;\n"
419    "}\n"
420    "public void set$capitalized_name$($type$ value) {\n");
421  if (IsReferenceType(GetJavaType(descriptor_))) {
422    printer->Print(variables_,
423      "  if (value == null) throw new java.lang.NullPointerException();\n");
424  }
425  printer->Print(variables_,
426    "  $name$_ = value;\n"
427    "  $set_has$;\n"
428    "}\n"
429    "public boolean has$capitalized_name$() {\n"
430    "  return $get_has$;\n"
431    "}\n"
432    "public void clear$capitalized_name$() {\n"
433    "  $name$_ = $default_copy_if_needed$;\n"
434    "  $clear_has$;\n"
435    "}\n");
436}
437
438void AccessorPrimitiveFieldGenerator::
439GenerateClearCode(io::Printer* printer) const {
440  printer->Print(variables_,
441    "$name$_ = $default_copy_if_needed$;\n");
442}
443
444void AccessorPrimitiveFieldGenerator::
445GenerateMergingCode(io::Printer* printer) const {
446  printer->Print(variables_,
447    "set$capitalized_name$(input.read$capitalized_type$());\n");
448}
449
450void AccessorPrimitiveFieldGenerator::
451GenerateSerializationCode(io::Printer* printer) const {
452  printer->Print(variables_,
453    "if (has$capitalized_name$()) {\n"
454    "  output.write$capitalized_type$($number$, $name$_);\n"
455    "}\n");
456}
457
458void AccessorPrimitiveFieldGenerator::
459GenerateSerializedSizeCode(io::Printer* printer) const {
460  printer->Print(variables_,
461    "if (has$capitalized_name$()) {\n"
462    "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
463    "      .compute$capitalized_type$Size($number$, $name$_);\n"
464    "}\n");
465}
466
467string AccessorPrimitiveFieldGenerator::GetBoxedType() const {
468  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
469}
470
471// ===================================================================
472
473RepeatedPrimitiveFieldGenerator::
474RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
475  : FieldGenerator(params), descriptor_(descriptor) {
476  SetPrimitiveVariables(descriptor, params, &variables_);
477}
478
479RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
480
481void RepeatedPrimitiveFieldGenerator::
482GenerateMembers(io::Printer* printer) const {
483  printer->Print(variables_,
484    "public $type$[] $name$ = $default$;\n");
485}
486
487void RepeatedPrimitiveFieldGenerator::
488GenerateClearCode(io::Printer* printer) const {
489  printer->Print(variables_,
490    "$name$ = $default$;\n");
491}
492
493void RepeatedPrimitiveFieldGenerator::
494GenerateMergingCode(io::Printer* printer) const {
495  // First, figure out the length of the array, then parse.
496  if (descriptor_->options().packed()) {
497    printer->Print(variables_,
498      "int length = input.readRawVarint32();\n"
499      "int limit = input.pushLimit(length);\n"
500      "// First pass to compute array length.\n"
501      "int arrayLength = 0;\n"
502      "int startPos = input.getPosition();\n"
503      "while (input.getBytesUntilLimit() > 0) {\n"
504      "  input.read$capitalized_type$();\n"
505      "  arrayLength++;\n"
506      "}\n"
507      "input.rewindToPosition(startPos);\n"
508      "this.$name$ = new $type$[arrayLength];\n"
509      "for (int i = 0; i < arrayLength; i++) {\n"
510      "  this.$name$[i] = input.read$capitalized_type$();\n"
511      "}\n"
512      "input.popLimit(limit);\n");
513  } else {
514    printer->Print(variables_,
515      "int arrayLength = com.google.protobuf.nano.WireFormatNano.getRepeatedFieldArrayLength(input, $tag$);\n"
516      "int i = this.$name$.length;\n");
517
518    if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
519      printer->Print(variables_,
520        "byte[][] newArray = new byte[i + arrayLength][];\n"
521        "System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
522        "this.$name$ = newArray;\n");
523    } else {
524      printer->Print(variables_,
525        "$type$[] newArray = new $type$[i + arrayLength];\n"
526        "System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
527        "this.$name$ = newArray;\n");
528    }
529    printer->Print(variables_,
530      "for (; i < this.$name$.length - 1; i++) {\n"
531      "  this.$name$[i] = input.read$capitalized_type$();\n"
532      "  input.readTag();\n"
533      "}\n"
534      "// Last one without readTag.\n"
535      "this.$name$[i] = input.read$capitalized_type$();\n");
536  }
537}
538
539void RepeatedPrimitiveFieldGenerator::
540GenerateRepeatedDataSizeCode(io::Printer* printer) const {
541  // Creates a variable dataSize and puts the serialized size in
542  // there.
543  if (FixedSize(descriptor_->type()) == -1) {
544    printer->Print(variables_,
545      "int dataSize = 0;\n"
546      "for ($type$ element : this.$name$) {\n"
547      "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
548      "    .compute$capitalized_type$SizeNoTag(element);\n"
549      "}\n");
550  } else {
551    printer->Print(variables_,
552      "int dataSize = $fixed_size$ * this.$name$.length;\n");
553  }
554}
555
556void RepeatedPrimitiveFieldGenerator::
557GenerateSerializationCode(io::Printer* printer) const {
558  if (descriptor_->options().packed()) {
559    printer->Print(variables_,
560      "if (this.$name$.length > 0) {\n");
561    printer->Indent();
562    GenerateRepeatedDataSizeCode(printer);
563    printer->Outdent();
564    printer->Print(variables_,
565      "  output.writeRawVarint32($tag$);\n"
566      "  output.writeRawVarint32(dataSize);\n"
567      "}\n");
568    printer->Print(variables_,
569      "for ($type$ element : this.$name$) {\n"
570      "  output.write$capitalized_type$NoTag(element);\n"
571      "}\n");
572  } else {
573    printer->Print(variables_,
574      "for ($type$ element : this.$name$) {\n"
575      "  output.write$capitalized_type$($number$, element);\n"
576      "}\n");
577  }
578}
579
580void RepeatedPrimitiveFieldGenerator::
581GenerateSerializedSizeCode(io::Printer* printer) const {
582  printer->Print(variables_,
583    "if (this.$name$.length > 0) {\n");
584  printer->Indent();
585
586  GenerateRepeatedDataSizeCode(printer);
587
588  printer->Print(
589    "size += dataSize;\n");
590  if (descriptor_->options().packed()) {
591    printer->Print(variables_,
592      "size += $tag_size$;\n"
593      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
594      "  .computeRawVarint32Size(dataSize);\n");
595  } else {
596    printer->Print(variables_,
597        "size += $tag_size$ * this.$name$.length;\n");
598  }
599
600  printer->Outdent();
601
602  printer->Print(
603    "}\n");
604}
605
606string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
607  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
608}
609
610}  // namespace javanano
611}  // namespace compiler
612}  // namespace protobuf
613}  // namespace google
614