java_message_field.cc revision fbaaef999ba563838ebd00874ed8a1c01fbf286d
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 (descriptor->type() == 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$_ = $type$.getDefaultInstance();\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:: 128GenerateMergingCode(io::Printer* printer) const { 129 printer->Print(variables_, 130 "if (other.has$capitalized_name$()) {\n" 131 " merge$capitalized_name$(other.get$capitalized_name$());\n" 132 "}\n"); 133} 134 135void MessageFieldGenerator:: 136GenerateBuildingCode(io::Printer* printer) const { 137 // Nothing to do for singular fields. 138} 139 140void MessageFieldGenerator:: 141GenerateParsingCode(io::Printer* printer) const { 142 printer->Print(variables_, 143 "$type$.Builder subBuilder = $type$.newBuilder();\n" 144 "if (has$capitalized_name$()) {\n" 145 " subBuilder.mergeFrom(get$capitalized_name$());\n" 146 "}\n"); 147 148 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 149 printer->Print(variables_, 150 "input.readGroup($number$, subBuilder, extensionRegistry);\n"); 151 } else { 152 printer->Print(variables_, 153 "input.readMessage(subBuilder, extensionRegistry);\n"); 154 } 155 156 printer->Print(variables_, 157 "set$capitalized_name$(subBuilder.buildPartial());\n"); 158} 159 160void MessageFieldGenerator:: 161GenerateSerializationCode(io::Printer* printer) const { 162 printer->Print(variables_, 163 "if (has$capitalized_name$()) {\n" 164 " output.write$group_or_message$($number$, get$capitalized_name$());\n" 165 "}\n"); 166} 167 168void MessageFieldGenerator:: 169GenerateSerializedSizeCode(io::Printer* printer) const { 170 printer->Print(variables_, 171 "if (has$capitalized_name$()) {\n" 172 " size += com.google.protobuf.CodedOutputStream\n" 173 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" 174 "}\n"); 175} 176 177string MessageFieldGenerator::GetBoxedType() const { 178 return ClassName(descriptor_->message_type()); 179} 180 181// =================================================================== 182 183RepeatedMessageFieldGenerator:: 184RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor) 185 : descriptor_(descriptor) { 186 SetMessageVariables(descriptor, &variables_); 187} 188 189RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} 190 191void RepeatedMessageFieldGenerator:: 192GenerateMembers(io::Printer* printer) const { 193 printer->Print(variables_, 194 "private java.util.List<$type$> $name$_ =\n" 195 " java.util.Collections.emptyList();\n" 196 "public java.util.List<$type$> get$capitalized_name$List() {\n" 197 " return $name$_;\n" // note: unmodifiable list 198 "}\n" 199 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 200 "public $type$ get$capitalized_name$(int index) {\n" 201 " return $name$_.get(index);\n" 202 "}\n"); 203} 204 205void RepeatedMessageFieldGenerator:: 206GenerateBuilderMembers(io::Printer* printer) const { 207 printer->Print(variables_, 208 // Note: We return an unmodifiable list because otherwise the caller 209 // could hold on to the returned list and modify it after the message 210 // has been built, thus mutating the message which is supposed to be 211 // immutable. 212 "public java.util.List<$type$> get$capitalized_name$List() {\n" 213 " return java.util.Collections.unmodifiableList(result.$name$_);\n" 214 "}\n" 215 "public int get$capitalized_name$Count() {\n" 216 " return result.get$capitalized_name$Count();\n" 217 "}\n" 218 "public $type$ get$capitalized_name$(int index) {\n" 219 " return result.get$capitalized_name$(index);\n" 220 "}\n" 221 "public Builder set$capitalized_name$(int index, $type$ value) {\n" 222 " if (value == null) {\n" 223 " throw new NullPointerException();\n" 224 " }\n" 225 " result.$name$_.set(index, value);\n" 226 " return this;\n" 227 "}\n" 228 "public Builder set$capitalized_name$(int index, " 229 "$type$.Builder builderForValue) {\n" 230 " result.$name$_.set(index, builderForValue.build());\n" 231 " return this;\n" 232 "}\n" 233 "public Builder add$capitalized_name$($type$ value) {\n" 234 " if (value == null) {\n" 235 " throw new NullPointerException();\n" 236 " }\n" 237 " if (result.$name$_.isEmpty()) {\n" 238 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 239 " }\n" 240 " result.$name$_.add(value);\n" 241 " return this;\n" 242 "}\n" 243 "public Builder add$capitalized_name$($type$.Builder builderForValue) {\n" 244 " if (result.$name$_.isEmpty()) {\n" 245 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 246 " }\n" 247 " result.$name$_.add(builderForValue.build());\n" 248 " return this;\n" 249 "}\n" 250 "public Builder addAll$capitalized_name$(\n" 251 " java.lang.Iterable<? extends $type$> values) {\n" 252 " if (result.$name$_.isEmpty()) {\n" 253 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 254 " }\n" 255 " super.addAll(values, result.$name$_);\n" 256 " return this;\n" 257 "}\n" 258 "public Builder clear$capitalized_name$() {\n" 259 " result.$name$_ = java.util.Collections.emptyList();\n" 260 " return this;\n" 261 "}\n"); 262} 263 264void RepeatedMessageFieldGenerator:: 265GenerateMergingCode(io::Printer* printer) const { 266 printer->Print(variables_, 267 "if (!other.$name$_.isEmpty()) {\n" 268 " if (result.$name$_.isEmpty()) {\n" 269 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 270 " }\n" 271 " result.$name$_.addAll(other.$name$_);\n" 272 "}\n"); 273} 274 275void RepeatedMessageFieldGenerator:: 276GenerateBuildingCode(io::Printer* printer) const { 277 printer->Print(variables_, 278 "if (result.$name$_ != java.util.Collections.EMPTY_LIST) {\n" 279 " result.$name$_ =\n" 280 " java.util.Collections.unmodifiableList(result.$name$_);\n" 281 "}\n"); 282} 283 284void RepeatedMessageFieldGenerator:: 285GenerateParsingCode(io::Printer* printer) const { 286 printer->Print(variables_, 287 "$type$.Builder subBuilder = $type$.newBuilder();\n"); 288 289 if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { 290 printer->Print(variables_, 291 "input.readGroup($number$, subBuilder, extensionRegistry);\n"); 292 } else { 293 printer->Print(variables_, 294 "input.readMessage(subBuilder, extensionRegistry);\n"); 295 } 296 297 printer->Print(variables_, 298 "add$capitalized_name$(subBuilder.buildPartial());\n"); 299} 300 301void RepeatedMessageFieldGenerator:: 302GenerateSerializationCode(io::Printer* printer) const { 303 printer->Print(variables_, 304 "for ($type$ element : get$capitalized_name$List()) {\n" 305 " output.write$group_or_message$($number$, element);\n" 306 "}\n"); 307} 308 309void RepeatedMessageFieldGenerator:: 310GenerateSerializedSizeCode(io::Printer* printer) const { 311 printer->Print(variables_, 312 "for ($type$ element : get$capitalized_name$List()) {\n" 313 " size += com.google.protobuf.CodedOutputStream\n" 314 " .compute$group_or_message$Size($number$, element);\n" 315 "}\n"); 316} 317 318string RepeatedMessageFieldGenerator::GetBoxedType() const { 319 return ClassName(descriptor_->message_type()); 320} 321 322} // namespace java 323} // namespace compiler 324} // namespace protobuf 325} // namespace google 326