javamicro_message_field.cc revision e2d542951c059563a3b7f74c257dac4f222d9dc5
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Based on original Protocol Buffers design by 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sanjay Ghemawat, Jeff Dean, and others. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/javamicro/javamicro_message_field.h> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/printer.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/wire_format.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace compiler { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace javamicro { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// repeat code between this and the other field types. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetMessageVariables(const Params& params, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* descriptor, map<string, string>* variables) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*variables)["name"] = 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnderscoresToCamelCase(descriptor); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*variables)["capitalized_name"] = 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnderscoresToCapitalizedCamelCase(descriptor); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*variables)["number"] = SimpleItoa(descriptor->number()); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*variables)["type"] = ClassName(params, descriptor->message_type()); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*variables)["group_or_message"] = 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Group" : "Message"; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*variables)["message_name"] = descriptor->containing_type()->name(); 65 //(*variables)["message_type"] = descriptor->message_type()->name(); 66} 67 68} // namespace 69 70// =================================================================== 71 72MessageFieldGenerator:: 73MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) 74 : FieldGenerator(params), descriptor_(descriptor) { 75 SetMessageVariables(params, descriptor, &variables_); 76} 77 78MessageFieldGenerator::~MessageFieldGenerator() {} 79 80void MessageFieldGenerator:: 81GenerateMembers(io::Printer* printer) const { 82 printer->Print(variables_, 83 "private boolean has$capitalized_name$;\n" 84// "private $type$ $name$_ = null;\n" 85// "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" 86// "public $type$ get$capitalized_name$() { return $name$_; }\n" 87 "private $type$ $name$_ = null;\n" 88 "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" 89 "public $type$ get$capitalized_name$() { return $name$_; }\n" 90 "public $message_name$ set$capitalized_name$($type$ value) {\n" 91 " if (value == null) {\n" 92 " throw new NullPointerException();\n" 93 " }\n" 94 " has$capitalized_name$ = true;\n" 95 " $name$_ = value;\n" 96 " return this;\n" 97 "}\n" 98 "public $message_name$ clear$capitalized_name$() {\n" 99 " has$capitalized_name$ = false;\n" 100 " $name$_ = null;\n" 101 " return this;\n" 102 "}\n"); 103} 104 105void MessageFieldGenerator:: 106GenerateMergingCode(io::Printer* printer) const { 107 printer->Print(variables_, 108 "if (other.has$capitalized_name$()) {\n" 109 " merge$capitalized_name$(other.get$capitalized_name$());\n" 110 "}\n"); 111} 112 113void MessageFieldGenerator:: 114GenerateParsingCode(io::Printer* printer) const { 115 printer->Print(variables_, 116 "$type$ value = new $type$();\n"); 117 118 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 119 printer->Print(variables_, 120 "input.readGroup(value, $number$);\n"); 121 } else { 122 printer->Print(variables_, 123 "input.readMessage(value);\n"); 124 } 125 126 printer->Print(variables_, 127 "set$capitalized_name$(value);\n"); 128} 129 130void MessageFieldGenerator:: 131GenerateSerializationCode(io::Printer* printer) const { 132 printer->Print(variables_, 133 "if (has$capitalized_name$()) {\n" 134 " output.write$group_or_message$($number$, get$capitalized_name$());\n" 135 "}\n"); 136} 137 138void MessageFieldGenerator:: 139GenerateSerializedSizeCode(io::Printer* printer) const { 140 printer->Print(variables_, 141 "if (has$capitalized_name$()) {\n" 142 " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" 143 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" 144 "}\n"); 145} 146 147string MessageFieldGenerator::GetBoxedType() const { 148 return ClassName(params_, descriptor_->message_type()); 149} 150 151// =================================================================== 152 153RepeatedMessageFieldGenerator:: 154RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params) 155 : FieldGenerator(params), descriptor_(descriptor) { 156 SetMessageVariables(params, descriptor, &variables_); 157} 158 159RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} 160 161void RepeatedMessageFieldGenerator:: 162GenerateMembers(io::Printer* printer) const { 163 if (params_.java_use_vector()) { 164 printer->Print(variables_, 165 "private java.util.Vector $name$_ = new java.util.Vector();\n" 166 "public java.util.Vector get$capitalized_name$List() {\n" 167 " return $name$_;\n" 168 "}\n" 169 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 170 "public $type$ get$capitalized_name$(int index) {\n" 171 " return ($type$) $name$_.elementAt(index);\n" 172 "}\n" 173 "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" 174 " if (value == null) {\n" 175 " throw new NullPointerException();\n" 176 " }\n" 177 " $name$_.setElementAt(value, index);\n" 178 " return this;\n" 179 "}\n" 180 "public $message_name$ add$capitalized_name$($type$ value) {\n" 181 " if (value == null) {\n" 182 " throw new NullPointerException();\n" 183 " }\n" 184 " $name$_.addElement(value);\n" 185 " return this;\n" 186 "}\n" 187 "public $message_name$ clear$capitalized_name$() {\n" 188 " $name$_.removeAllElements();\n" 189 " return this;\n" 190 "}\n"); 191 } else { 192 printer->Print(variables_, 193 "private java.util.List<$type$> $name$_ =\n" 194 " java.util.Collections.emptyList();\n" 195 "public java.util.List<$type$> get$capitalized_name$List() {\n" 196 " return $name$_;\n" 197 "}\n" 198 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 199 "public $type$ get$capitalized_name$(int index) {\n" 200 " return $name$_.get(index);\n" 201 "}\n" 202 "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" 203 " if (value == null) {\n" 204 " throw new NullPointerException();\n" 205 " }\n" 206 " $name$_.set(index, value);\n" 207 " return this;\n" 208 "}\n" 209 "public $message_name$ add$capitalized_name$($type$ value) {\n" 210 " if (value == null) {\n" 211 " throw new NullPointerException();\n" 212 " }\n" 213 " if ($name$_.isEmpty()) {\n" 214 " $name$_ = new java.util.ArrayList<$type$>();\n" 215 " }\n" 216 " $name$_.add(value);\n" 217 " return this;\n" 218 "}\n" 219 "public $message_name$ clear$capitalized_name$() {\n" 220 " $name$_ = java.util.Collections.emptyList();\n" 221 " return this;\n" 222 "}\n"); 223 } 224} 225 226void RepeatedMessageFieldGenerator:: 227GenerateMergingCode(io::Printer* printer) const { 228 if (params_.java_use_vector()) { 229 printer->Print(variables_, 230 "if (other.$name$_.size() != 0) {\n" 231 " for (int i = 0; i < other.$name$_.size(); i++) {\n" 232 " result.$name$_.addElement(other.$name$_.elementAt(i));\n" 233 " }\n" 234 "}\n"); 235 } else { 236 printer->Print(variables_, 237 "if (!other.$name$_.isEmpty()) {\n" 238 " if (result.$name$_.isEmpty()) {\n" 239 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 240 " }\n" 241 " result.$name$_.addAll(other.$name$_);\n" 242 "}\n"); 243 } 244} 245 246void RepeatedMessageFieldGenerator:: 247GenerateParsingCode(io::Printer* printer) const { 248 printer->Print(variables_, 249 "$type$ value = new $type$();\n"); 250 251 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 252 printer->Print(variables_, 253 "input.readGroup(value, $number$);\n"); 254 } else { 255 printer->Print(variables_, 256 "input.readMessage(value);\n"); 257 } 258 259 printer->Print(variables_, 260 "add$capitalized_name$(value);\n"); 261} 262 263void RepeatedMessageFieldGenerator:: 264GenerateSerializationCode(io::Printer* printer) const { 265 if (params_.java_use_vector()) { 266 printer->Print(variables_, 267 "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" 268 " output.write$group_or_message$($number$, get$capitalized_name$(i));\n" 269 "}\n"); 270 } else { 271 printer->Print(variables_, 272 "for ($type$ element : get$capitalized_name$List()) {\n" 273 " output.write$group_or_message$($number$, element);\n" 274 "}\n"); 275 } 276} 277 278void RepeatedMessageFieldGenerator:: 279GenerateSerializedSizeCode(io::Printer* printer) const { 280 if (params_.java_use_vector()) { 281 printer->Print(variables_, 282 "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" 283 " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" 284 " .compute$group_or_message$Size($number$, get$capitalized_name$(i));\n" 285 "}\n"); 286 } else { 287 printer->Print(variables_, 288 "for ($type$ element : get$capitalized_name$List()) {\n" 289 " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" 290 " .compute$group_or_message$Size($number$, element);\n" 291 "}\n"); 292 } 293} 294 295string RepeatedMessageFieldGenerator::GetBoxedType() const { 296 return ClassName(params_, descriptor_->message_type()); 297} 298 299} // namespace javamicro 300} // namespace compiler 301} // namespace protobuf 302} // namespace google 303