164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Protocol Buffers - Google's data interchange format
264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Copyright 2008 Google Inc.  All rights reserved.
364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// http://code.google.com/p/protobuf/
464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Redistribution and use in source and binary forms, with or without
664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// modification, are permitted provided that the following conditions are
764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// met:
864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Redistributions of source code must retain the above copyright
1064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// notice, this list of conditions and the following disclaimer.
1164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Redistributions in binary form must reproduce the above
1264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// copyright notice, this list of conditions and the following disclaimer
1364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// in the documentation and/or other materials provided with the
1464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// distribution.
1564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//     * Neither the name of Google Inc. nor the names of its
1664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// contributors may be used to endorse or promote products derived from
1764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// this software without specific prior written permission.
1864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//
1964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Author: kenton@google.com (Kenton Varda)
3264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//  Based on original Protocol Buffers design by
3364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci//  Sanjay Ghemawat, Jeff Dean, and others.
3464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <map>
360f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith#include <math.h>
3764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <string>
3864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
3964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
4064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/common.h>
4164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/compiler/javanano/javanano_helpers.h>
4264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/io/printer.h>
4364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/wire_format.h>
4464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/strutil.h>
4564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci#include <google/protobuf/stubs/substitute.h>
4664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
4764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace google {
4864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace protobuf {
4964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace compiler {
5064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace javanano {
5164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
5264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciusing internal::WireFormat;
5364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciusing internal::WireFormatLite;
5464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
5564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcinamespace {
5664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
5764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char* PrimitiveTypeName(JavaType type) {
5864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (type) {
5964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return "int";
6064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return "long";
6164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return "float";
6264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return "double";
6364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return "boolean";
6464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return "java.lang.String";
6564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return "byte[]";
6664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return NULL;
6764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return NULL;
6864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
6964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
7064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
7164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
7264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
7364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
7464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return NULL;
7564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
7664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
7764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcibool IsReferenceType(JavaType type) {
7864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (type) {
7964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return false;
8064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return false;
8164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return false;
8264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return false;
8364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return false;
8464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return true;
8564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return true;
8664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return false;
8764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return true;
8864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
8964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
9064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
9164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
9264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
9364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
9464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return false;
9564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
9664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
9764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcibool IsArrayType(JavaType type) {
9864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (type) {
9964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return false;
10064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return false;
10164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return false;
10264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return false;
10364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return false;
10464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return false;
10564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return true;
10664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return false;
10764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return false;
10864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
10964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
11064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
11164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
11264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
11364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
11464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return false;
11564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
11664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
11764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciconst char* GetCapitalizedType(const FieldDescriptor* field) {
11864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (field->type()) {
11964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT32   : return "Int32"   ;
12064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT32  : return "UInt32"  ;
12164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT32  : return "SInt32"  ;
12264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ;
12364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
12464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT64   : return "Int64"   ;
12564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT64  : return "UInt64"  ;
12664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT64  : return "SInt64"  ;
12764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ;
12864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
12964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FLOAT   : return "Float"   ;
13064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_DOUBLE  : return "Double"  ;
13164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BOOL    : return "Bool"    ;
13264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_STRING  : return "String"  ;
13364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BYTES   : return "Bytes"   ;
13464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_ENUM    : return "Enum"    ;
13564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_GROUP   : return "Group"   ;
13664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_MESSAGE : return "Message" ;
13764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
13864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
13964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // types are added.
14064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
14164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
14364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return NULL;
14464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
14564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
14664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// For encodings with fixed sizes, returns that size in bytes.  Otherwise
14764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// returns -1.
14864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazciint FixedSize(FieldDescriptor::Type type) {
14964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (type) {
15064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT32   : return -1;
15164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_INT64   : return -1;
15264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT32  : return -1;
15364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_UINT64  : return -1;
15464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT32  : return -1;
15564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SINT64  : return -1;
15664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
15764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
15864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
15964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
16064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
16164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
16264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
16364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::kBoolSize;
16464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_ENUM    : return -1;
16564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
16664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_STRING  : return -1;
16764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_BYTES   : return -1;
16864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_GROUP   : return -1;
16964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case FieldDescriptor::TYPE_MESSAGE : return -1;
17064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
17164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
17264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // types are added.
17364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
17464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
17564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return -1;
17664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
17764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
1780f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith// Returns true if the field has a default value equal to NaN.
1790f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smithbool IsDefaultNaN(const FieldDescriptor* field) {
1800f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith  switch (field->type()) {
1810f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_INT32   : return false;
1820f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_UINT32  : return false;
1830f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_SINT32  : return false;
1840f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_FIXED32 : return false;
1850f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_SFIXED32: return false;
1860f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_INT64   : return false;
1870f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_UINT64  : return false;
1880f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_SINT64  : return false;
1890f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_FIXED64 : return false;
1900f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_SFIXED64: return false;
1910f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_FLOAT   :
1920f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      return isnan(field->default_value_float());
1930f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_DOUBLE  :
1940f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith      return isnan(field->default_value_double());
1950f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_BOOL    : return false;
1960f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_STRING  : return false;
1970f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_BYTES   : return false;
1980f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_ENUM    : return false;
1990f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_GROUP   : return false;
2000f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    case FieldDescriptor::TYPE_MESSAGE : return false;
2010f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith
2020f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    // No default because we want the compiler to complain if any new
2030f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith    // types are added.
2040f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith  }
2050f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith
2060f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith  GOOGLE_LOG(FATAL) << "Can't get here.";
2070f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith  return false;
2080f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith}
2090f2ca89132ab81441f7eb351c7a053a8c8d9d1c3Chris Smith
21064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// Return true if the type is a that has variable length
21164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// for instance String's.
21264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcibool IsVariableLenType(JavaType type) {
21364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  switch (type) {
21464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_INT    : return false;
21564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_LONG   : return false;
21664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_FLOAT  : return false;
21764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_DOUBLE : return false;
21864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BOOLEAN: return false;
21964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_STRING : return true;
22064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_BYTES  : return true;
22164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_ENUM   : return false;
22264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    case JAVATYPE_MESSAGE: return true;
22364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
22464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // No default because we want the compiler to complain if any new
22564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // JavaTypes are added.
22664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
22764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
22864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  GOOGLE_LOG(FATAL) << "Can't get here.";
22964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return false;
23064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
23164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
23264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcibool AllAscii(const string& text) {
23364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  for (int i = 0; i < text.size(); i++) {
23464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if ((text[i] & 0x80) != 0) {
23564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      return false;
23664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
23764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
23864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return true;
23964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
24064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
24164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
24264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci                           map<string, string>* variables) {
24364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["name"] =
244f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
24564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["capitalized_name"] =
246f4e01452f159ae6b53f5edd25fa647ca2919ae10Tom Chao    RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
24764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["number"] = SimpleItoa(descriptor->number());
24864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
24964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["default"] = DefaultValue(params, descriptor);
25064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
25164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // For C++-string types (string and bytes), we might need to have
25264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // the generated code do the unicode decoding (see comments in
25364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // InternalNano.java for gory details.). We would like to do this
25464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // once into a "private static final" field and re-use that from
25564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // then on.
25664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
25764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      !descriptor->default_value_string().empty()) {
25864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    string default_value;
25964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
26064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      default_value = strings::Substitute(
26164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci          "com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
26264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci          CEscape(descriptor->default_value_string()));
26364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
26464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      if (AllAscii(descriptor->default_value_string())) {
26564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        // All chars are ASCII.  In this case CEscape() works fine.
26664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        default_value = "\"" + CEscape(descriptor->default_value_string()) + "\"";
26764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      } else {
26864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        default_value = strings::Substitute(
26964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci            "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
27064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci            CEscape(descriptor->default_value_string()));
27164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      }
27264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
27364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    (*variables)["default_constant_value"] = default_value;
27464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
27564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
27664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
27764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
27864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["tag_size"] = SimpleItoa(
27964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      WireFormat::TagSize(descriptor->number(), descriptor->type()));
28064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (IsReferenceType(GetJavaType(descriptor))) {
28164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    (*variables)["null_check"] =
28264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        "  if (value == null) {\n"
28364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        "    throw new NullPointerException();\n"
28464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        "  }\n";
28564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
28664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    (*variables)["null_check"] = "";
28764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
28864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  int fixed_size = FixedSize(descriptor->type());
28964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (fixed_size != -1) {
29064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
29164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
29264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["message_name"] = descriptor->containing_type()->name();
29364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  (*variables)["empty_array_name"] = EmptyArrayName(params, descriptor);
29464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
29564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace
29664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
29764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// ===================================================================
29864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
29964d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciPrimitiveFieldGenerator::
30064d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
30164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  : FieldGenerator(params), descriptor_(descriptor) {
30264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  SetPrimitiveVariables(descriptor, params, &variables_);
30364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
30464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
30564d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciPrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
30664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
30764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid PrimitiveFieldGenerator::
30864d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateMembers(io::Printer* printer) const {
30964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (variables_.find("default_constant_value") != variables_.end()) {
31064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    // Those primitive types that need a saved default.
31164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
31264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "private static final $type$ $default_constant$ = $default_constant_value$;\n");
31364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    if (descriptor_->type() == FieldDescriptor::TYPE_BYTES) {
31464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      printer->Print(variables_,
31564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        "public $type$ $name$ = $default$.clone();\n");
31664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    } else {
31764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      printer->Print(variables_,
31864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci        "public $type$ $name$ = $default$;\n");
31964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    }
32064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
32164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
32264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "public $type$ $name$ = $default$;\n");
32364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
32435d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci
32535d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  if (params_.generate_has()) {
32635d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
32735d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "public boolean has$capitalized_name$ = false;\n");
32835d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  }
32964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
33064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
33164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid PrimitiveFieldGenerator::
33264d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateParsingCode(io::Printer* printer) const {
33364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  printer->Print(variables_,
3340f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci    "this.$name$ = input.read$capitalized_type$();\n");
33535d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci
33635d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  if (params_.generate_has()) {
33735d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
33835d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "has$capitalized_name$ = true;\n");
33935d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  }
34035d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci}
34135d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci
34235d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazcivoid PrimitiveFieldGenerator::
34335d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas KirazciGenerateSerializationConditional(io::Printer* printer) const {
34435d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  if (params_.generate_has()) {
34535d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
34635d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "if (has$capitalized_name$ || ");
34735d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  } else {
34835d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
34935d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "if (");
35035d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  }
35135d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  if (IsArrayType(GetJavaType(descriptor_))) {
35235d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
35335d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "!java.util.Arrays.equals(this.$name$, $default$)) {\n");
35435d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  } else if (IsReferenceType(GetJavaType(descriptor_))) {
35535d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
35635d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "!this.$name$.equals($default$)) {\n");
35735d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  } else if (IsDefaultNaN(descriptor_)) {
35835d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
35935d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "!$capitalized_type$.isNaN(this.$name$)) {\n");
36035d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  } else {
36135d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    printer->Print(variables_,
36235d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci      "this.$name$ != $default$) {\n");
36335d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci  }
36464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
36564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
36664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid PrimitiveFieldGenerator::
36764d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateSerializationCode(io::Printer* printer) const {
36864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (descriptor_->is_required()) {
36964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
3700f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "output.write$capitalized_type$($number$, this.$name$);\n");
37164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
37235d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    GenerateSerializationConditional(printer);
37364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
3740f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "  output.write$capitalized_type$($number$, this.$name$);\n"
37564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n");
37664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
37764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
37864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
37964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid PrimitiveFieldGenerator::
38064d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateSerializedSizeCode(io::Printer* printer) const {
38164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (descriptor_->is_required()) {
38264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
38364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
3840f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "    .compute$capitalized_type$Size($number$, this.$name$);\n");
38564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
38635d9fd84ff1d9ecdb91156b757cc9fdcc3f25249Ulas Kirazci    GenerateSerializationConditional(printer);
38764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
38864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
3890f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "      .compute$capitalized_type$Size($number$, this.$name$);\n"
39064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n");
39164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
39264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
39364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
39464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring PrimitiveFieldGenerator::GetBoxedType() const {
39564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
39664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
39764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
39864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci// ===================================================================
39964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
40064d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciRepeatedPrimitiveFieldGenerator::
40164d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciRepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
40264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  : FieldGenerator(params), descriptor_(descriptor) {
40364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  SetPrimitiveVariables(descriptor, params, &variables_);
40464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
40564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
40664d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciRepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
40764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
40864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid RepeatedPrimitiveFieldGenerator::
40964d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateMembers(io::Printer* printer) const {
41064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  printer->Print(variables_,
41164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    "public $type$[] $name$ = $default$;\n");
41264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
41364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
41464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid RepeatedPrimitiveFieldGenerator::
41564d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateParsingCode(io::Printer* printer) const {
41664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  // First, figure out the length of the array, then parse.
41764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (descriptor_->options().packed()) {
41864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
41964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "int length = input.readRawVarint32();\n"
42064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "int limit = input.pushLimit(length);\n"
42164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "// First pass to compute array length.\n"
42264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "int arrayLength = 0;\n"
42364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "int startPos = input.getPosition();\n"
42464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "while (input.getBytesUntilLimit() > 0) {\n"
42564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "  input.read$capitalized_type$();\n"
42664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "  arrayLength++;\n"
42764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n"
42864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "input.rewindToPosition(startPos);\n"
4290f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "this.$name$ = new $type$[arrayLength];\n"
43064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "for (int i = 0; i < arrayLength; i++) {\n"
4310f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "  this.$name$[i] = input.read$capitalized_type$();\n"
43264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n"
43364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "input.popLimit(limit);\n");
43464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
43564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
43664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "int arrayLength = com.google.protobuf.nano.WireFormatNano.getRepeatedFieldArrayLength(input, $tag$);\n"
437710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick      "int i = this.$name$.length;\n");
438710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick
439710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick    if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
440710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick      printer->Print(variables_,
441710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick        "byte[][] newArray = new byte[i + arrayLength][];\n"
442710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick        "System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
443710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick        "this.$name$ = newArray;\n");
444710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick    } else {
445710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick      printer->Print(variables_,
446710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick        "$type$[] newArray = new $type$[i + arrayLength];\n"
447710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick        "System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
448710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick        "this.$name$ = newArray;\n");
449710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick    }
450710ca66fdd31db8f3920b122292bdc3250d5aadaFicus Kirkpatrick    printer->Print(variables_,
4510f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "for (; i < this.$name$.length - 1; i++) {\n"
4520f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "  this.$name$[i] = input.read$capitalized_type$();\n"
45364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "  input.readTag();\n"
45464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n"
45564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "// Last one without readTag.\n"
4560f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "this.$name$[i] = input.read$capitalized_type$();\n");
45764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
45864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
45964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
46064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid RepeatedPrimitiveFieldGenerator::
46114dd1f02ac95f61087e311bf61c85047fb218a29Ulas KirazciGenerateRepeatedDataSizeCode(io::Printer* printer) const {
46214dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci  // Creates a variable dataSize and puts the serialized size in
46314dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci  // there.
46414dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci  if (FixedSize(descriptor_->type()) == -1) {
46514dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci    printer->Print(variables_,
46614dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "int dataSize = 0;\n"
46714dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "for ($type$ element : this.$name$) {\n"
46814dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
46914dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "    .compute$capitalized_type$SizeNoTag(element);\n"
47014dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "}\n");
47114dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci  } else {
47214dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci    printer->Print(variables_,
47314dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "int dataSize = $fixed_size$ * this.$name$.length;\n");
47414dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci  }
47514dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci}
47614dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci
47714dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazcivoid RepeatedPrimitiveFieldGenerator::
47864d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateSerializationCode(io::Printer* printer) const {
47964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (descriptor_->options().packed()) {
48064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
48114dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "if (this.$name$.length > 0) {\n");
48214dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci    printer->Indent();
48314dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci    GenerateRepeatedDataSizeCode(printer);
48414dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci    printer->Outdent();
48514dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci    printer->Print(variables_,
48664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "  output.writeRawVarint32($tag$);\n"
48714dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "  output.writeRawVarint32(dataSize);\n"
48864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n");
48964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
4900f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "for ($type$ element : this.$name$) {\n"
49164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "  output.write$capitalized_type$NoTag(element);\n"
49264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n");
49364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
49464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
4950f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci      "for ($type$ element : this.$name$) {\n"
49664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "  output.write$capitalized_type$($number$, element);\n"
49764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "}\n");
49864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
49964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
50064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
50164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcivoid RepeatedPrimitiveFieldGenerator::
50264d8d8f89050c5ada85341f967af391f4716a7cbUlas KirazciGenerateSerializedSizeCode(io::Printer* printer) const {
50364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  printer->Print(variables_,
5040f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci    "if (this.$name$.length > 0) {\n");
50564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  printer->Indent();
50664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
50714dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci  GenerateRepeatedDataSizeCode(printer);
50864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
50964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  printer->Print(
51064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    "size += dataSize;\n");
51164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  if (descriptor_->options().packed()) {
51264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
51364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "size += $tag_size$;\n"
51464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
51514dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci      "  .computeRawVarint32Size(dataSize);\n");
51664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  } else {
51764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci    printer->Print(variables_,
5180f1c4eb967517e21701a3b425d115baff5d15b4fUlas Kirazci        "size += $tag_size$ * this.$name$.length;\n");
51964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  }
52064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
52164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  printer->Outdent();
52264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
52314dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci  printer->Print(
52414dd1f02ac95f61087e311bf61c85047fb218a29Ulas Kirazci    "}\n");
52564d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
52664d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
52764d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazcistring RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
52864d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
52964d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}
53064d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci
53164d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace javanano
53264d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace compiler
53364d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace protobuf
53464d8d8f89050c5ada85341f967af391f4716a7cbUlas Kirazci}  // namespace google
535