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/java/java_message_field.h> 39#include <google/protobuf/compiler/java/java_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 java { 48 49namespace { 50 51// TODO(kenton): Factor out a "SetCommonFieldVariables()" to get rid of 52// repeat code between this and the other field types. 53void SetMessageVariables(const FieldDescriptor* descriptor, 54 map<string, string>* variables) { 55 (*variables)["name"] = 56 UnderscoresToCamelCase(descriptor); 57 (*variables)["capitalized_name"] = 58 UnderscoresToCapitalizedCamelCase(descriptor); 59 (*variables)["number"] = SimpleItoa(descriptor->number()); 60 (*variables)["type"] = ClassName(descriptor->message_type()); 61 (*variables)["group_or_message"] = 62 (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? 63 "Group" : "Message"; 64} 65 66} // namespace 67 68// =================================================================== 69 70MessageFieldGenerator:: 71MessageFieldGenerator(const FieldDescriptor* descriptor) 72 : descriptor_(descriptor) { 73 SetMessageVariables(descriptor, &variables_); 74} 75 76MessageFieldGenerator::~MessageFieldGenerator() {} 77 78void MessageFieldGenerator:: 79GenerateMembers(io::Printer* printer) const { 80 printer->Print(variables_, 81 "private boolean has$capitalized_name$;\n" 82 "private $type$ $name$_;\n" 83 "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n" 84 "public $type$ get$capitalized_name$() { return $name$_; }\n"); 85} 86 87void MessageFieldGenerator:: 88GenerateBuilderMembers(io::Printer* printer) const { 89 printer->Print(variables_, 90 "public boolean has$capitalized_name$() {\n" 91 " return result.has$capitalized_name$();\n" 92 "}\n" 93 "public $type$ get$capitalized_name$() {\n" 94 " return result.get$capitalized_name$();\n" 95 "}\n" 96 "public Builder set$capitalized_name$($type$ value) {\n" 97 " if (value == null) {\n" 98 " throw new NullPointerException();\n" 99 " }\n" 100 " result.has$capitalized_name$ = true;\n" 101 " result.$name$_ = value;\n" 102 " return this;\n" 103 "}\n" 104 "public Builder set$capitalized_name$($type$.Builder builderForValue) {\n" 105 " result.has$capitalized_name$ = true;\n" 106 " result.$name$_ = builderForValue.build();\n" 107 " return this;\n" 108 "}\n" 109 "public Builder merge$capitalized_name$($type$ value) {\n" 110 " if (result.has$capitalized_name$() &&\n" 111 " result.$name$_ != $type$.getDefaultInstance()) {\n" 112 " result.$name$_ =\n" 113 " $type$.newBuilder(result.$name$_).mergeFrom(value).buildPartial();\n" 114 " } else {\n" 115 " result.$name$_ = value;\n" 116 " }\n" 117 " result.has$capitalized_name$ = true;\n" 118 " return this;\n" 119 "}\n" 120 "public Builder clear$capitalized_name$() {\n" 121 " result.has$capitalized_name$ = false;\n" 122 " result.$name$_ = $type$.getDefaultInstance();\n" 123 " return this;\n" 124 "}\n"); 125} 126 127void MessageFieldGenerator:: 128GenerateInitializationCode(io::Printer* printer) const { 129 printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n"); 130} 131 132void MessageFieldGenerator:: 133GenerateMergingCode(io::Printer* printer) const { 134 printer->Print(variables_, 135 "if (other.has$capitalized_name$()) {\n" 136 " merge$capitalized_name$(other.get$capitalized_name$());\n" 137 "}\n"); 138} 139 140void MessageFieldGenerator:: 141GenerateBuildingCode(io::Printer* printer) const { 142 // Nothing to do for singular fields. 143} 144 145void MessageFieldGenerator:: 146GenerateParsingCode(io::Printer* printer) const { 147 printer->Print(variables_, 148 "$type$.Builder subBuilder = $type$.newBuilder();\n" 149 "if (has$capitalized_name$()) {\n" 150 " subBuilder.mergeFrom(get$capitalized_name$());\n" 151 "}\n"); 152 153 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { 154 printer->Print(variables_, 155 "input.readGroup($number$, subBuilder, extensionRegistry);\n"); 156 } else { 157 printer->Print(variables_, 158 "input.readMessage(subBuilder, extensionRegistry);\n"); 159 } 160 161 printer->Print(variables_, 162 "set$capitalized_name$(subBuilder.buildPartial());\n"); 163} 164 165void MessageFieldGenerator:: 166GenerateSerializationCode(io::Printer* printer) const { 167 printer->Print(variables_, 168 "if (has$capitalized_name$()) {\n" 169 " output.write$group_or_message$($number$, get$capitalized_name$());\n" 170 "}\n"); 171} 172 173void MessageFieldGenerator:: 174GenerateSerializedSizeCode(io::Printer* printer) const { 175 printer->Print(variables_, 176 "if (has$capitalized_name$()) {\n" 177 " size += com.google.protobuf.CodedOutputStream\n" 178 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" 179 "}\n"); 180} 181 182string MessageFieldGenerator::GetBoxedType() const { 183 return ClassName(descriptor_->message_type()); 184} 185 186// =================================================================== 187 188RepeatedMessageFieldGenerator:: 189RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor) 190 : descriptor_(descriptor) { 191 SetMessageVariables(descriptor, &variables_); 192} 193 194RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} 195 196void RepeatedMessageFieldGenerator:: 197GenerateMembers(io::Printer* printer) const { 198 printer->Print(variables_, 199 "private java.util.List<$type$> $name$_ =\n" 200 " java.util.Collections.emptyList();\n" 201 "public java.util.List<$type$> get$capitalized_name$List() {\n" 202 " return $name$_;\n" // note: unmodifiable list 203 "}\n" 204 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 205 "public $type$ get$capitalized_name$(int index) {\n" 206 " return $name$_.get(index);\n" 207 "}\n"); 208} 209 210void RepeatedMessageFieldGenerator:: 211GenerateBuilderMembers(io::Printer* printer) const { 212 printer->Print(variables_, 213 // Note: We return an unmodifiable list because otherwise the caller 214 // could hold on to the returned list and modify it after the message 215 // has been built, thus mutating the message which is supposed to be 216 // immutable. 217 "public java.util.List<$type$> get$capitalized_name$List() {\n" 218 " return java.util.Collections.unmodifiableList(result.$name$_);\n" 219 "}\n" 220 "public int get$capitalized_name$Count() {\n" 221 " return result.get$capitalized_name$Count();\n" 222 "}\n" 223 "public $type$ get$capitalized_name$(int index) {\n" 224 " return result.get$capitalized_name$(index);\n" 225 "}\n" 226 "public Builder set$capitalized_name$(int index, $type$ value) {\n" 227 " if (value == null) {\n" 228 " throw new NullPointerException();\n" 229 " }\n" 230 " result.$name$_.set(index, value);\n" 231 " return this;\n" 232 "}\n" 233 "public Builder set$capitalized_name$(int index, " 234 "$type$.Builder builderForValue) {\n" 235 " result.$name$_.set(index, builderForValue.build());\n" 236 " return this;\n" 237 "}\n" 238 "public Builder add$capitalized_name$($type$ value) {\n" 239 " if (value == null) {\n" 240 " throw new NullPointerException();\n" 241 " }\n" 242 " if (result.$name$_.isEmpty()) {\n" 243 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 244 " }\n" 245 " result.$name$_.add(value);\n" 246 " return this;\n" 247 "}\n" 248 "public Builder add$capitalized_name$($type$.Builder builderForValue) {\n" 249 " if (result.$name$_.isEmpty()) {\n" 250 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 251 " }\n" 252 " result.$name$_.add(builderForValue.build());\n" 253 " return this;\n" 254 "}\n" 255 "public Builder addAll$capitalized_name$(\n" 256 " java.lang.Iterable<? extends $type$> values) {\n" 257 " if (result.$name$_.isEmpty()) {\n" 258 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 259 " }\n" 260 " super.addAll(values, result.$name$_);\n" 261 " return this;\n" 262 "}\n" 263 "public Builder clear$capitalized_name$() {\n" 264 " result.$name$_ = java.util.Collections.emptyList();\n" 265 " return this;\n" 266 "}\n"); 267} 268 269void RepeatedMessageFieldGenerator:: 270GenerateInitializationCode(io::Printer* printer) const { 271 // Initialized inline. 272} 273 274void RepeatedMessageFieldGenerator:: 275GenerateMergingCode(io::Printer* printer) const { 276 printer->Print(variables_, 277 "if (!other.$name$_.isEmpty()) {\n" 278 " if (result.$name$_.isEmpty()) {\n" 279 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 280 " }\n" 281 " result.$name$_.addAll(other.$name$_);\n" 282 "}\n"); 283} 284 285void RepeatedMessageFieldGenerator:: 286GenerateBuildingCode(io::Printer* printer) const { 287 printer->Print(variables_, 288 "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n" 289 " result.$name$_ =\n" 290 " java.util.Collections.unmodifiableList(result.$name$_);\n" 291 "}\n"); 292} 293 294void RepeatedMessageFieldGenerator:: 295GenerateParsingCode(io::Printer* printer) const { 296 printer->Print(variables_, 297 "$type$.Builder subBuilder = $type$.newBuilder();\n"); 298 299 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { 300 printer->Print(variables_, 301 "input.readGroup($number$, subBuilder, extensionRegistry);\n"); 302 } else { 303 printer->Print(variables_, 304 "input.readMessage(subBuilder, extensionRegistry);\n"); 305 } 306 307 printer->Print(variables_, 308 "add$capitalized_name$(subBuilder.buildPartial());\n"); 309} 310 311void RepeatedMessageFieldGenerator:: 312GenerateSerializationCode(io::Printer* printer) const { 313 printer->Print(variables_, 314 "for ($type$ element : get$capitalized_name$List()) {\n" 315 " output.write$group_or_message$($number$, element);\n" 316 "}\n"); 317} 318 319void RepeatedMessageFieldGenerator:: 320GenerateSerializedSizeCode(io::Printer* printer) const { 321 printer->Print(variables_, 322 "for ($type$ element : get$capitalized_name$List()) {\n" 323 " size += com.google.protobuf.CodedOutputStream\n" 324 " .compute$group_or_message$Size($number$, element);\n" 325 "}\n"); 326} 327 328string RepeatedMessageFieldGenerator::GetBoxedType() const { 329 return ClassName(descriptor_->message_type()); 330} 331 332} // namespace java 333} // namespace compiler 334} // namespace protobuf 335} // namespace google 336