javanano_message_field.cc revision e74fe623e115237968a3de1143d7cdb4df710858
1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34 35#include <map> 36#include <string> 37 38#include <google/protobuf/compiler/javanano/javanano_message_field.h> 39#include <google/protobuf/compiler/javanano/javanano_helpers.h> 40#include <google/protobuf/io/printer.h> 41#include <google/protobuf/wire_format.h> 42#include <google/protobuf/stubs/strutil.h> 43 44namespace google { 45namespace protobuf { 46namespace compiler { 47namespace javanano { 48 49using internal::WireFormat; 50using internal::WireFormatLite; 51 52namespace { 53 54// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of 55// repeat code between this and the other field types. 56void SetMessageVariables(const Params& params, 57 const FieldDescriptor* descriptor, map<string, string>* variables) { 58 (*variables)["name"] = 59 RenameJavaKeywords(UnderscoresToCamelCase(descriptor)); 60 (*variables)["capitalized_name"] = 61 RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor)); 62 (*variables)["number"] = SimpleItoa(descriptor->number()); 63 (*variables)["type"] = ClassName(params, descriptor->message_type()); 64 (*variables)["group_or_message"] = 65 (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? 66 "Group" : "Message"; 67 (*variables)["message_name"] = descriptor->containing_type()->name(); 68 //(*variables)["message_type"] = descriptor->message_type()->name(); 69 (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); 70} 71 72} // namespace 73 74// =================================================================== 75 76MessageFieldGenerator:: 77MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) 78 : FieldGenerator(params), descriptor_(descriptor) { 79 SetMessageVariables(params, descriptor, &variables_); 80} 81 82MessageFieldGenerator::~MessageFieldGenerator() {} 83 84void MessageFieldGenerator:: 85GenerateMembers(io::Printer* printer) const { 86 printer->Print(variables_, 87 "public $type$ $name$ = null;\n"); 88} 89 90void MessageFieldGenerator:: 91GenerateClearCode(io::Printer* printer) const { 92 printer->Print(variables_, 93 "$name$ = null;\n"); 94} 95 96void MessageFieldGenerator:: 97GenerateMergingCode(io::Printer* printer) const { 98 printer->Print(variables_, 99 "if (this.$name$ == null) {\n" 100 " this.$name$ = new $type$();\n" 101 "}"); 102 103 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 104 printer->Print(variables_, 105 "input.readGroup(this.$name$, $number$);\n"); 106 } else { 107 printer->Print(variables_, 108 "input.readMessage(this.$name$);\n"); 109 } 110} 111 112void MessageFieldGenerator:: 113GenerateSerializationCode(io::Printer* printer) const { 114 printer->Print(variables_, 115 "if (this.$name$ != null) {\n" 116 " output.write$group_or_message$($number$, this.$name$);\n" 117 "}\n"); 118} 119 120void MessageFieldGenerator:: 121GenerateSerializedSizeCode(io::Printer* printer) const { 122 printer->Print(variables_, 123 "if (this.$name$ != null) {\n" 124 " size += com.google.protobuf.nano.CodedOutputByteBufferNano\n" 125 " .compute$group_or_message$Size($number$, this.$name$);\n" 126 "}\n"); 127} 128 129string MessageFieldGenerator::GetBoxedType() const { 130 return ClassName(params_, descriptor_->message_type()); 131} 132 133// =================================================================== 134 135AccessorMessageFieldGenerator:: 136AccessorMessageFieldGenerator( 137 const FieldDescriptor* descriptor, const Params& params) 138 : FieldGenerator(params), descriptor_(descriptor) { 139 SetMessageVariables(params, descriptor, &variables_); 140} 141 142AccessorMessageFieldGenerator::~AccessorMessageFieldGenerator() {} 143 144void AccessorMessageFieldGenerator:: 145GenerateMembers(io::Printer* printer) const { 146 printer->Print(variables_, 147 "private $type$ $name$_ = null;\n" 148 "public $type$ get$capitalized_name$() {\n" 149 " return $name$_;\n" 150 "}\n" 151 "public void set$capitalized_name$($type$ value) {\n" 152 " if (value == null) {\n" 153 " throw new java.lang.NullPointerException();\n" 154 " }\n" 155 " $name$_ = value;\n" 156 "}\n" 157 "public boolean has$capitalized_name$() {\n" 158 " return $name$_ != null;\n" 159 "}\n" 160 "public void clear$capitalized_name$() {\n" 161 " $name$_ = null;\n" 162 "}\n"); 163} 164 165void AccessorMessageFieldGenerator:: 166GenerateClearCode(io::Printer* printer) const { 167 printer->Print(variables_, 168 "$name$_ = null;\n"); 169} 170 171void AccessorMessageFieldGenerator:: 172GenerateMergingCode(io::Printer* printer) const { 173 printer->Print(variables_, 174 "if (!has$capitalized_name$()) {\n" 175 " set$capitalized_name$(new $type$());\n" 176 "}"); 177 178 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 179 printer->Print(variables_, 180 "input.readGroup($name$_, $number$);\n"); 181 } else { 182 printer->Print(variables_, 183 "input.readMessage($name$_);\n"); 184 } 185} 186 187void AccessorMessageFieldGenerator:: 188GenerateSerializationCode(io::Printer* printer) const { 189 printer->Print(variables_, 190 "if (has$capitalized_name$()) {\n" 191 " output.write$group_or_message$($number$, $name$_);\n" 192 "}\n"); 193} 194 195void AccessorMessageFieldGenerator:: 196GenerateSerializedSizeCode(io::Printer* printer) const { 197 printer->Print(variables_, 198 "if (has$capitalized_name$()) {\n" 199 " size += com.google.protobuf.nano.CodedOutputByteBufferNano\n" 200 " .compute$group_or_message$Size($number$, $name$_);\n" 201 "}\n"); 202} 203 204string AccessorMessageFieldGenerator::GetBoxedType() const { 205 return ClassName(params_, descriptor_->message_type()); 206} 207 208// =================================================================== 209 210RepeatedMessageFieldGenerator:: 211RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) 212 : FieldGenerator(params), descriptor_(descriptor) { 213 SetMessageVariables(params, descriptor, &variables_); 214} 215 216RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} 217 218void RepeatedMessageFieldGenerator:: 219GenerateMembers(io::Printer* printer) const { 220 printer->Print(variables_, 221 "public $type$[] $name$ = $type$.EMPTY_ARRAY;\n"); 222} 223 224void RepeatedMessageFieldGenerator:: 225GenerateClearCode(io::Printer* printer) const { 226 printer->Print(variables_, 227 "$name$ = $type$.EMPTY_ARRAY;\n"); 228} 229 230void RepeatedMessageFieldGenerator:: 231GenerateMergingCode(io::Printer* printer) const { 232 // First, figure out the length of the array, then parse. 233 printer->Print(variables_, 234 "int arrayLength = com.google.protobuf.nano.WireFormatNano.getRepeatedFieldArrayLength(input, $tag$);\n" 235 "int i = this.$name$.length;\n" 236 "$type$[] newArray = new $type$[i + arrayLength];\n" 237 "System.arraycopy(this.$name$, 0, newArray, 0, i);\n" 238 "this.$name$ = newArray;\n" 239 "for (; i < this.$name$.length - 1; i++) {\n" 240 " this.$name$[i] = new $type$();\n"); 241 242 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 243 printer->Print(variables_, 244 " input.readGroup(this.$name$[i], $number$);\n"); 245 } else { 246 printer->Print(variables_, 247 " input.readMessage(this.$name$[i]);\n"); 248 } 249 250 printer->Print(variables_, 251 " input.readTag();\n" 252 "}\n" 253 "// Last one without readTag.\n" 254 "this.$name$[i] = new $type$();\n"); 255 256 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 257 printer->Print(variables_, 258 "input.readGroup(this.$name$[i], $number$);\n"); 259 } else { 260 printer->Print(variables_, 261 "input.readMessage(this.$name$[i]);\n"); 262 } 263} 264 265void RepeatedMessageFieldGenerator:: 266GenerateSerializationCode(io::Printer* printer) const { 267 printer->Print(variables_, 268 "for ($type$ element : this.$name$) {\n" 269 " output.write$group_or_message$($number$, element);\n" 270 "}\n"); 271} 272 273void RepeatedMessageFieldGenerator:: 274GenerateSerializedSizeCode(io::Printer* printer) const { 275 printer->Print(variables_, 276 "for ($type$ element : this.$name$) {\n" 277 " size += com.google.protobuf.nano.CodedOutputByteBufferNano\n" 278 " .compute$group_or_message$Size($number$, element);\n" 279 "}\n"); 280} 281 282string RepeatedMessageFieldGenerator::GetBoxedType() const { 283 return ClassName(params_, descriptor_->message_type()); 284} 285 286} // namespace javanano 287} // namespace compiler 288} // namespace protobuf 289} // namespace google 290