blob: 178bbe19004633f45b4fda820df455dc3e85c8a4 [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00002// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
temporal40ee5512008-07-10 02:12:20 +00004//
kenton@google.com24bf56f2008-09-24 20:31:01 +00005// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
temporal40ee5512008-07-10 02:12:20 +00008//
kenton@google.com24bf56f2008-09-24 20:31:01 +00009// * 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.
temporal40ee5512008-07-10 02:12:20 +000018//
kenton@google.com24bf56f2008-09-24 20:31:01 +000019// 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.
temporal40ee5512008-07-10 02:12:20 +000030
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
Feng Xiaoeee38b02015-08-22 18:25:48 -070038#include <google/protobuf/stubs/logging.h>
temporal40ee5512008-07-10 02:12:20 +000039#include <google/protobuf/stubs/common.h>
jieluo@google.com4de8f552014-07-18 00:47:59 +000040#include <google/protobuf/compiler/java/java_context.h>
41#include <google/protobuf/compiler/java/java_doc_comment.h>
temporal40ee5512008-07-10 02:12:20 +000042#include <google/protobuf/compiler/java/java_helpers.h>
jieluo@google.com4de8f552014-07-18 00:47:59 +000043#include <google/protobuf/compiler/java/java_name_resolver.h>
44#include <google/protobuf/compiler/java/java_primitive_field.h>
temporal40ee5512008-07-10 02:12:20 +000045#include <google/protobuf/io/printer.h>
kenton@google.com80b1d622009-07-29 01:13:20 +000046#include <google/protobuf/wire_format.h>
temporal40ee5512008-07-10 02:12:20 +000047#include <google/protobuf/stubs/strutil.h>
temporal40ee5512008-07-10 02:12:20 +000048
49namespace google {
50namespace protobuf {
51namespace compiler {
52namespace java {
53
kenton@google.com2d6daa72009-01-22 01:27:00 +000054using internal::WireFormat;
kenton@google.com80b1d622009-07-29 01:13:20 +000055using internal::WireFormatLite;
kenton@google.com2d6daa72009-01-22 01:27:00 +000056
temporal40ee5512008-07-10 02:12:20 +000057namespace {
58
temporal40ee5512008-07-10 02:12:20 +000059void SetPrimitiveVariables(const FieldDescriptor* descriptor,
liujisi@google.com33165fe2010-11-02 13:14:58 +000060 int messageBitIndex,
61 int builderBitIndex,
jieluo@google.com4de8f552014-07-18 00:47:59 +000062 const FieldGeneratorInfo* info,
63 ClassNameResolver* name_resolver,
temporal40ee5512008-07-10 02:12:20 +000064 map<string, string>* variables) {
jieluo@google.com4de8f552014-07-18 00:47:59 +000065 SetCommonFieldVariables(descriptor, info, variables);
66
temporal40ee5512008-07-10 02:12:20 +000067 (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
68 (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
liujisi@google.com33165fe2010-11-02 13:14:58 +000069 (*variables)["field_type"] = (*variables)["type"];
70 (*variables)["field_list_type"] = "java.util.List<" +
71 (*variables)["boxed_type"] + ">";
liujisi@google.com295a0962011-07-05 06:16:40 +000072 (*variables)["empty_list"] = "java.util.Collections.emptyList()";
jieluo@google.com4de8f552014-07-18 00:47:59 +000073 (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
liujisi@google.com33165fe2010-11-02 13:14:58 +000074 (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
jieluo@google.com4de8f552014-07-18 00:47:59 +000075 "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
76 (*variables)["capitalized_type"] =
77 GetCapitalizedType(descriptor, /* immutable = */ true);
Bo Yang5db21732015-05-21 14:28:59 -070078 if (descriptor->is_packed()) {
79 (*variables)["tag"] = SimpleItoa(WireFormatLite::MakeTag(
80 descriptor->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
81 } else {
82 (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
83 }
kenton@google.com2d6daa72009-01-22 01:27:00 +000084 (*variables)["tag_size"] = SimpleItoa(
kenton@google.comfccb1462009-12-18 02:11:36 +000085 WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
kenton@google.com2d6daa72009-01-22 01:27:00 +000086 if (IsReferenceType(GetJavaType(descriptor))) {
87 (*variables)["null_check"] =
88 " if (value == null) {\n"
89 " throw new NullPointerException();\n"
90 " }\n";
91 } else {
92 (*variables)["null_check"] = "";
93 }
liujisi@google.com33165fe2010-11-02 13:14:58 +000094 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
95 // by the proto compiler
96 (*variables)["deprecation"] = descriptor->options().deprecated()
97 ? "@java.lang.Deprecated " : "";
kenton@google.comfccb1462009-12-18 02:11:36 +000098 int fixed_size = FixedSize(GetType(descriptor));
kenton@google.com2d6daa72009-01-22 01:27:00 +000099 if (fixed_size != -1) {
100 (*variables)["fixed_size"] = SimpleItoa(fixed_size);
101 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000102 (*variables)["on_changed"] =
103 HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
104
jieluo@google.com4de8f552014-07-18 00:47:59 +0000105 if (SupportFieldPresence(descriptor->file())) {
106 // For singular messages and builders, one bit is used for the hasField bit.
107 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
108 (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000109
jieluo@google.com4de8f552014-07-18 00:47:59 +0000110 // Note that these have a trailing ";".
111 (*variables)["set_has_field_bit_message"] =
112 GenerateSetBit(messageBitIndex) + ";";
113 (*variables)["set_has_field_bit_builder"] =
114 GenerateSetBit(builderBitIndex) + ";";
115 (*variables)["clear_has_field_bit_builder"] =
116 GenerateClearBit(builderBitIndex) + ";";
117
118 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
119 } else {
120 (*variables)["set_has_field_bit_message"] = "";
121 (*variables)["set_has_field_bit_builder"] = "";
122 (*variables)["clear_has_field_bit_builder"] = "";
123
124 if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
125 (*variables)["is_field_present_message"] =
126 "!" + (*variables)["name"] + "_.isEmpty()";
127 } else {
128 (*variables)["is_field_present_message"] =
129 (*variables)["name"] + "_ != " + (*variables)["default"];
130 }
131 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000132
133 // For repated builders, one bit is used for whether the array is immutable.
134 (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
135 (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
136 (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
137
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000138 // For repeated fields, one bit is used for whether the array is immutable
139 // in the parsing constructor.
140 (*variables)["get_mutable_bit_parser"] =
141 GenerateGetBitMutableLocal(builderBitIndex);
142 (*variables)["set_mutable_bit_parser"] =
143 GenerateSetBitMutableLocal(builderBitIndex);
144
liujisi@google.com33165fe2010-11-02 13:14:58 +0000145 (*variables)["get_has_field_bit_from_local"] =
146 GenerateGetBitFromLocal(builderBitIndex);
147 (*variables)["set_has_field_bit_to_local"] =
148 GenerateSetBitToLocal(messageBitIndex);
temporal40ee5512008-07-10 02:12:20 +0000149}
liujisi@google.com33165fe2010-11-02 13:14:58 +0000150
temporal40ee5512008-07-10 02:12:20 +0000151} // namespace
152
153// ===================================================================
154
jieluo@google.com4de8f552014-07-18 00:47:59 +0000155ImmutablePrimitiveFieldGenerator::
156ImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
157 int messageBitIndex,
158 int builderBitIndex,
159 Context* context)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000160 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
jieluo@google.com4de8f552014-07-18 00:47:59 +0000161 builderBitIndex_(builderBitIndex), context_(context),
162 name_resolver_(context->GetNameResolver()) {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000163 SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000164 context->GetFieldGeneratorInfo(descriptor),
165 name_resolver_, &variables_);
temporal40ee5512008-07-10 02:12:20 +0000166}
167
jieluo@google.com4de8f552014-07-18 00:47:59 +0000168ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
temporal40ee5512008-07-10 02:12:20 +0000169
jieluo@google.com4de8f552014-07-18 00:47:59 +0000170int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000171 return 1;
172}
173
jieluo@google.com4de8f552014-07-18 00:47:59 +0000174int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000175 return 1;
176}
177
jieluo@google.com4de8f552014-07-18 00:47:59 +0000178void ImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000179GenerateInterfaceMembers(io::Printer* printer) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000180 if (SupportFieldPresence(descriptor_->file())) {
181 WriteFieldDocComment(printer, descriptor_);
182 printer->Print(variables_,
183 "$deprecation$boolean has$capitalized_name$();\n");
184 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000185 WriteFieldDocComment(printer, descriptor_);
186 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000187 "$deprecation$$type$ get$capitalized_name$();\n");
188}
189
jieluo@google.com4de8f552014-07-18 00:47:59 +0000190void ImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000191GenerateMembers(io::Printer* printer) const {
192 printer->Print(variables_,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000193 "private $field_type$ $name$_;\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000194 PrintExtraFieldInfo(variables_, printer);
195 if (SupportFieldPresence(descriptor_->file())) {
196 WriteFieldDocComment(printer, descriptor_);
197 printer->Print(variables_,
198 "$deprecation$public boolean has$capitalized_name$() {\n"
199 " return $get_has_field_bit_message$;\n"
200 "}\n");
201 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000202
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000203 WriteFieldDocComment(printer, descriptor_);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000204 printer->Print(variables_,
205 "$deprecation$public $type$ get$capitalized_name$() {\n"
206 " return $name$_;\n"
207 "}\n");
temporal40ee5512008-07-10 02:12:20 +0000208}
209
jieluo@google.com4de8f552014-07-18 00:47:59 +0000210void ImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000211GenerateBuilderMembers(io::Printer* printer) const {
212 printer->Print(variables_,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000213 "private $field_type$ $name$_ $default_init$;\n");
214
jieluo@google.com4de8f552014-07-18 00:47:59 +0000215 if (SupportFieldPresence(descriptor_->file())) {
216 WriteFieldDocComment(printer, descriptor_);
217 printer->Print(variables_,
218 "$deprecation$public boolean has$capitalized_name$() {\n"
219 " return $get_has_field_bit_builder$;\n"
220 "}\n");
221 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000222
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000223 WriteFieldDocComment(printer, descriptor_);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000224 printer->Print(variables_,
225 "$deprecation$public $type$ get$capitalized_name$() {\n"
226 " return $name$_;\n"
227 "}\n");
228
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000229 WriteFieldDocComment(printer, descriptor_);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000230 printer->Print(variables_,
231 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000232 "$null_check$"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000233 " $set_has_field_bit_builder$\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000234 " $name$_ = value;\n"
235 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000236 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000237 "}\n");
238
239 WriteFieldDocComment(printer, descriptor_);
240 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000241 "$deprecation$public Builder clear$capitalized_name$() {\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000242 " $clear_has_field_bit_builder$\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000243 JavaType type = GetJavaType(descriptor_);
244 if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000245 // The default value is not a simple literal so we want to avoid executing
246 // it multiple times. Instead, get the default out of the default instance.
247 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000248 " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000249 } else {
250 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000251 " $name$_ = $default$;\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000252 }
253 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000254 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000255 " return this;\n"
256 "}\n");
257}
258
jieluo@google.com4de8f552014-07-18 00:47:59 +0000259void ImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000260GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
261 // noop for primitives
262}
263
jieluo@google.com4de8f552014-07-18 00:47:59 +0000264void ImmutablePrimitiveFieldGenerator::
kenton@google.comfccb1462009-12-18 02:11:36 +0000265GenerateInitializationCode(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000266 printer->Print(variables_, "$name$_ = $default$;\n");
267}
268
jieluo@google.com4de8f552014-07-18 00:47:59 +0000269void ImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000270GenerateBuilderClearCode(io::Printer* printer) const {
271 printer->Print(variables_,
272 "$name$_ = $default$;\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000273 "$clear_has_field_bit_builder$\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000274}
275
jieluo@google.com4de8f552014-07-18 00:47:59 +0000276void ImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000277GenerateMergingCode(io::Printer* printer) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000278 if (SupportFieldPresence(descriptor_->file())) {
279 printer->Print(variables_,
280 "if (other.has$capitalized_name$()) {\n"
281 " set$capitalized_name$(other.get$capitalized_name$());\n"
282 "}\n");
283 } else {
284 printer->Print(variables_,
285 "if (other.get$capitalized_name$() != $default$) {\n"
286 " set$capitalized_name$(other.get$capitalized_name$());\n"
287 "}\n");
288 }
temporal40ee5512008-07-10 02:12:20 +0000289}
290
jieluo@google.com4de8f552014-07-18 00:47:59 +0000291void ImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000292GenerateBuildingCode(io::Printer* printer) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000293 if (SupportFieldPresence(descriptor_->file())) {
294 printer->Print(variables_,
295 "if ($get_has_field_bit_from_local$) {\n"
296 " $set_has_field_bit_to_local$;\n"
297 "}\n");
298 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000299 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000300 "result.$name$_ = $name$_;\n");
temporal40ee5512008-07-10 02:12:20 +0000301}
302
jieluo@google.com4de8f552014-07-18 00:47:59 +0000303void ImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000304GenerateParsingCode(io::Printer* printer) const {
305 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000306 "$set_has_field_bit_message$\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000307 "$name$_ = input.read$capitalized_type$();\n");
temporal40ee5512008-07-10 02:12:20 +0000308}
309
jieluo@google.com4de8f552014-07-18 00:47:59 +0000310void ImmutablePrimitiveFieldGenerator::
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000311GenerateParsingDoneCode(io::Printer* printer) const {
312 // noop for primitives.
313}
314
jieluo@google.com4de8f552014-07-18 00:47:59 +0000315void ImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000316GenerateSerializationCode(io::Printer* printer) const {
kenton@google.coma4a9ef82010-09-17 23:20:04 +0000317 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000318 "if ($is_field_present_message$) {\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000319 " output.write$capitalized_type$($number$, $name$_);\n"
kenton@google.coma4a9ef82010-09-17 23:20:04 +0000320 "}\n");
temporal40ee5512008-07-10 02:12:20 +0000321}
322
jieluo@google.com4de8f552014-07-18 00:47:59 +0000323void ImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000324GenerateSerializedSizeCode(io::Printer* printer) const {
kenton@google.coma4a9ef82010-09-17 23:20:04 +0000325 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000326 "if ($is_field_present_message$) {\n"
kenton@google.coma4a9ef82010-09-17 23:20:04 +0000327 " size += com.google.protobuf.CodedOutputStream\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000328 " .compute$capitalized_type$Size($number$, $name$_);\n"
kenton@google.coma4a9ef82010-09-17 23:20:04 +0000329 "}\n");
temporal40ee5512008-07-10 02:12:20 +0000330}
331
jieluo@google.com4de8f552014-07-18 00:47:59 +0000332void ImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000333GenerateEqualsCode(io::Printer* printer) const {
334 switch (GetJavaType(descriptor_)) {
335 case JAVATYPE_INT:
336 case JAVATYPE_LONG:
337 case JAVATYPE_BOOLEAN:
338 printer->Print(variables_,
339 "result = result && (get$capitalized_name$()\n"
340 " == other.get$capitalized_name$());\n");
341 break;
342
343 case JAVATYPE_FLOAT:
344 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000345 "result = result && (\n"
346 " java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
347 " == java.lang.Float.floatToIntBits(\n"
348 " other.get$capitalized_name$()));\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000349 break;
350
351 case JAVATYPE_DOUBLE:
352 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000353 "result = result && (\n"
354 " java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
355 " == java.lang.Double.doubleToLongBits(\n"
356 " other.get$capitalized_name$()));\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000357 break;
358
359 case JAVATYPE_STRING:
360 case JAVATYPE_BYTES:
361 printer->Print(variables_,
362 "result = result && get$capitalized_name$()\n"
363 " .equals(other.get$capitalized_name$());\n");
364 break;
365
366 case JAVATYPE_ENUM:
367 case JAVATYPE_MESSAGE:
368 default:
369 GOOGLE_LOG(FATAL) << "Can't get here.";
370 break;
371 }
372}
373
jieluo@google.com4de8f552014-07-18 00:47:59 +0000374void ImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000375GenerateHashCode(io::Printer* printer) const {
376 printer->Print(variables_,
377 "hash = (37 * hash) + $constant_name$;\n");
378 switch (GetJavaType(descriptor_)) {
379 case JAVATYPE_INT:
380 printer->Print(variables_,
381 "hash = (53 * hash) + get$capitalized_name$();\n");
382 break;
383
384 case JAVATYPE_LONG:
385 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000386 "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
387 " get$capitalized_name$());\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000388 break;
389
390 case JAVATYPE_BOOLEAN:
391 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000392 "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"
393 " get$capitalized_name$());\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000394 break;
395
396 case JAVATYPE_FLOAT:
397 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000398 "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000399 " get$capitalized_name$());\n");
400 break;
401
402 case JAVATYPE_DOUBLE:
403 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000404 "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
405 " java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000406 break;
407
408 case JAVATYPE_STRING:
409 case JAVATYPE_BYTES:
410 printer->Print(variables_,
411 "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
412 break;
413
414 case JAVATYPE_ENUM:
415 case JAVATYPE_MESSAGE:
416 default:
417 GOOGLE_LOG(FATAL) << "Can't get here.";
418 break;
419 }
420}
421
jieluo@google.com4de8f552014-07-18 00:47:59 +0000422string ImmutablePrimitiveFieldGenerator::GetBoxedType() const {
temporal40ee5512008-07-10 02:12:20 +0000423 return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
424}
425
426// ===================================================================
427
jieluo@google.com4de8f552014-07-18 00:47:59 +0000428ImmutablePrimitiveOneofFieldGenerator::
429ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
430 int messageBitIndex,
431 int builderBitIndex,
432 Context* context)
433 : ImmutablePrimitiveFieldGenerator(
434 descriptor, messageBitIndex, builderBitIndex, context) {
435 const OneofGeneratorInfo* info =
436 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
437 SetCommonOneofVariables(descriptor, info, &variables_);
temporal40ee5512008-07-10 02:12:20 +0000438}
439
jieluo@google.com4de8f552014-07-18 00:47:59 +0000440ImmutablePrimitiveOneofFieldGenerator::
441~ImmutablePrimitiveOneofFieldGenerator() {}
temporal40ee5512008-07-10 02:12:20 +0000442
jieluo@google.com4de8f552014-07-18 00:47:59 +0000443void ImmutablePrimitiveOneofFieldGenerator::
444GenerateMembers(io::Printer* printer) const {
445 PrintExtraFieldInfo(variables_, printer);
446 if (SupportFieldPresence(descriptor_->file())) {
447 WriteFieldDocComment(printer, descriptor_);
448 printer->Print(variables_,
449 "$deprecation$public boolean has$capitalized_name$() {\n"
450 " return $has_oneof_case_message$;\n"
451 "}\n");
452 }
453
454 WriteFieldDocComment(printer, descriptor_);
455 printer->Print(variables_,
456 "$deprecation$public $type$ get$capitalized_name$() {\n"
457 " if ($has_oneof_case_message$) {\n"
458 " return ($boxed_type$) $oneof_name$_;\n"
459 " }\n"
460 " return $default$;\n"
461 "}\n");
462}
463
464
465void ImmutablePrimitiveOneofFieldGenerator::
466GenerateBuilderMembers(io::Printer* printer) const {
467 if (SupportFieldPresence(descriptor_->file())) {
468 WriteFieldDocComment(printer, descriptor_);
469 printer->Print(variables_,
470 "$deprecation$public boolean has$capitalized_name$() {\n"
471 " return $has_oneof_case_message$;\n"
472 "}\n");
473 }
474
475 WriteFieldDocComment(printer, descriptor_);
476 printer->Print(variables_,
477 "$deprecation$public $type$ get$capitalized_name$() {\n"
478 " if ($has_oneof_case_message$) {\n"
479 " return ($boxed_type$) $oneof_name$_;\n"
480 " }\n"
481 " return $default$;\n"
482 "}\n");
483
484 WriteFieldDocComment(printer, descriptor_);
485 printer->Print(variables_,
486 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
487 "$null_check$"
488 " $set_oneof_case_message$;\n"
489 " $oneof_name$_ = value;\n"
490 " $on_changed$\n"
491 " return this;\n"
492 "}\n");
493
494 WriteFieldDocComment(printer, descriptor_);
495 printer->Print(variables_,
496 "$deprecation$public Builder clear$capitalized_name$() {\n"
497 " if ($has_oneof_case_message$) {\n"
498 " $clear_oneof_case_message$;\n"
499 " $oneof_name$_ = null;\n"
500 " $on_changed$\n"
501 " }\n"
502 " return this;\n"
503 "}\n");
504}
505
506void ImmutablePrimitiveOneofFieldGenerator::
507GenerateBuildingCode(io::Printer* printer) const {
508 printer->Print(variables_,
509 "if ($has_oneof_case_message$) {\n"
510 " result.$oneof_name$_ = $oneof_name$_;\n"
511 "}\n");
512}
513
514void ImmutablePrimitiveOneofFieldGenerator::
515GenerateMergingCode(io::Printer* printer) const {
516 printer->Print(variables_,
517 "set$capitalized_name$(other.get$capitalized_name$());\n");
518}
519
520void ImmutablePrimitiveOneofFieldGenerator::
521GenerateParsingCode(io::Printer* printer) const {
522 printer->Print(variables_,
523 "$set_oneof_case_message$;\n"
524 "$oneof_name$_ = input.read$capitalized_type$();\n");
525}
526
527void ImmutablePrimitiveOneofFieldGenerator::
528GenerateSerializationCode(io::Printer* printer) const {
529 printer->Print(variables_,
530 "if ($has_oneof_case_message$) {\n"
531 " output.write$capitalized_type$(\n"
532 " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
533 "}\n");
534}
535
536void ImmutablePrimitiveOneofFieldGenerator::
537GenerateSerializedSizeCode(io::Printer* printer) const {
538 printer->Print(variables_,
539 "if ($has_oneof_case_message$) {\n"
540 " size += com.google.protobuf.CodedOutputStream\n"
541 " .compute$capitalized_type$Size(\n"
542 " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
543 "}\n");
544}
545
546// ===================================================================
547
548RepeatedImmutablePrimitiveFieldGenerator::
549RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
550 int messageBitIndex,
551 int builderBitIndex,
552 Context* context)
553 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
554 builderBitIndex_(builderBitIndex), context_(context),
555 name_resolver_(context->GetNameResolver()) {
556 SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
557 context->GetFieldGeneratorInfo(descriptor),
558 name_resolver_, &variables_);
559}
560
561RepeatedImmutablePrimitiveFieldGenerator::
562~RepeatedImmutablePrimitiveFieldGenerator() {}
563
564int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000565 return 0;
566}
567
jieluo@google.com4de8f552014-07-18 00:47:59 +0000568int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000569 return 1;
570}
571
jieluo@google.com4de8f552014-07-18 00:47:59 +0000572void RepeatedImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000573GenerateInterfaceMembers(io::Printer* printer) const {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000574 WriteFieldDocComment(printer, descriptor_);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000575 printer->Print(variables_,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000576 "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n");
577 WriteFieldDocComment(printer, descriptor_);
578 printer->Print(variables_,
579 "$deprecation$int get$capitalized_name$Count();\n");
580 WriteFieldDocComment(printer, descriptor_);
581 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000582 "$deprecation$$type$ get$capitalized_name$(int index);\n");
583}
584
585
jieluo@google.com4de8f552014-07-18 00:47:59 +0000586void RepeatedImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000587GenerateMembers(io::Printer* printer) const {
588 printer->Print(variables_,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000589 "private $field_list_type$ $name$_;\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000590 PrintExtraFieldInfo(variables_, printer);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000591 WriteFieldDocComment(printer, descriptor_);
592 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000593 "$deprecation$public java.util.List<$boxed_type$>\n"
594 " get$capitalized_name$List() {\n"
temporal40ee5512008-07-10 02:12:20 +0000595 " return $name$_;\n" // note: unmodifiable list
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000596 "}\n");
597 WriteFieldDocComment(printer, descriptor_);
598 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000599 "$deprecation$public int get$capitalized_name$Count() {\n"
600 " return $name$_.size();\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000601 "}\n");
602 WriteFieldDocComment(printer, descriptor_);
603 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000604 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
temporal40ee5512008-07-10 02:12:20 +0000605 " return $name$_.get(index);\n"
606 "}\n");
kenton@google.com2d6daa72009-01-22 01:27:00 +0000607
Bo Yang5db21732015-05-21 14:28:59 -0700608 if (descriptor_->is_packed() &&
kenton@google.com80b1d622009-07-29 01:13:20 +0000609 HasGeneratedMethods(descriptor_->containing_type())) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000610 printer->Print(variables_,
jasonh+personal@google.com99512332009-12-01 18:05:21 +0000611 "private int $name$MemoizedSerializedSize = -1;\n");
kenton@google.com2d6daa72009-01-22 01:27:00 +0000612 }
temporal40ee5512008-07-10 02:12:20 +0000613}
614
jieluo@google.com4de8f552014-07-18 00:47:59 +0000615void RepeatedImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000616GenerateBuilderMembers(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000617 // One field is the list and the bit field keeps track of whether the
618 // list is immutable. If it's immutable, the invariant is that it must
619 // either an instance of Collections.emptyList() or it's an ArrayList
620 // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
621 // a refererence to the underlying ArrayList. This invariant allows us to
622 // share instances of lists between protocol buffers avoiding expensive
623 // memory allocations. Note, immutable is a strong guarantee here -- not
624 // just that the list cannot be modified via the reference but that the
625 // list can never be modified.
temporal40ee5512008-07-10 02:12:20 +0000626 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000627 "private $field_list_type$ $name$_ = $empty_list$;\n");
628
629 printer->Print(variables_,
630 "private void ensure$capitalized_name$IsMutable() {\n"
631 " if (!$get_mutable_bit_builder$) {\n"
632 " $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
633 " $set_mutable_bit_builder$;\n"
634 " }\n"
635 "}\n");
636
temporal40ee5512008-07-10 02:12:20 +0000637 // Note: We return an unmodifiable list because otherwise the caller
638 // could hold on to the returned list and modify it after the message
639 // has been built, thus mutating the message which is supposed to be
640 // immutable.
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000641 WriteFieldDocComment(printer, descriptor_);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000642 printer->Print(variables_,
643 "$deprecation$public java.util.List<$boxed_type$>\n"
644 " get$capitalized_name$List() {\n"
645 " return java.util.Collections.unmodifiableList($name$_);\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000646 "}\n");
647 WriteFieldDocComment(printer, descriptor_);
648 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000649 "$deprecation$public int get$capitalized_name$Count() {\n"
650 " return $name$_.size();\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000651 "}\n");
652 WriteFieldDocComment(printer, descriptor_);
653 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000654 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
655 " return $name$_.get(index);\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000656 "}\n");
657 WriteFieldDocComment(printer, descriptor_);
658 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000659 "$deprecation$public Builder set$capitalized_name$(\n"
660 " int index, $type$ value) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000661 "$null_check$"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000662 " ensure$capitalized_name$IsMutable();\n"
663 " $name$_.set(index, value);\n"
664 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000665 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000666 "}\n");
667 WriteFieldDocComment(printer, descriptor_);
668 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000669 "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000670 "$null_check$"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000671 " ensure$capitalized_name$IsMutable();\n"
672 " $name$_.add(value);\n"
673 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000674 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000675 "}\n");
676 WriteFieldDocComment(printer, descriptor_);
677 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000678 "$deprecation$public Builder addAll$capitalized_name$(\n"
temporal40ee5512008-07-10 02:12:20 +0000679 " java.lang.Iterable<? extends $boxed_type$> values) {\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000680 " ensure$capitalized_name$IsMutable();\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000681 " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
682 " values, $name$_);\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000683 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000684 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000685 "}\n");
686 WriteFieldDocComment(printer, descriptor_);
687 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000688 "$deprecation$public Builder clear$capitalized_name$() {\n"
689 " $name$_ = $empty_list$;\n"
690 " $clear_mutable_bit_builder$;\n"
691 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000692 " return this;\n"
693 "}\n");
694}
695
jieluo@google.com4de8f552014-07-18 00:47:59 +0000696void RepeatedImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000697GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
698 // noop for primitives
699}
700
jieluo@google.com4de8f552014-07-18 00:47:59 +0000701void RepeatedImmutablePrimitiveFieldGenerator::
kenton@google.comfccb1462009-12-18 02:11:36 +0000702GenerateInitializationCode(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000703 printer->Print(variables_, "$name$_ = $empty_list$;\n");
704}
705
jieluo@google.com4de8f552014-07-18 00:47:59 +0000706void RepeatedImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000707GenerateBuilderClearCode(io::Printer* printer) const {
708 printer->Print(variables_,
709 "$name$_ = $empty_list$;\n"
710 "$clear_mutable_bit_builder$;\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000711}
712
jieluo@google.com4de8f552014-07-18 00:47:59 +0000713void RepeatedImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000714GenerateMergingCode(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000715 // The code below does two optimizations:
716 // 1. If the other list is empty, there's nothing to do. This ensures we
717 // don't allocate a new array if we already have an immutable one.
718 // 2. If the other list is non-empty and our current list is empty, we can
719 // reuse the other list which is guaranteed to be immutable.
temporal40ee5512008-07-10 02:12:20 +0000720 printer->Print(variables_,
721 "if (!other.$name$_.isEmpty()) {\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000722 " if ($name$_.isEmpty()) {\n"
723 " $name$_ = other.$name$_;\n"
724 " $clear_mutable_bit_builder$;\n"
725 " } else {\n"
726 " ensure$capitalized_name$IsMutable();\n"
727 " $name$_.addAll(other.$name$_);\n"
temporal40ee5512008-07-10 02:12:20 +0000728 " }\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000729 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000730 "}\n");
731}
732
jieluo@google.com4de8f552014-07-18 00:47:59 +0000733void RepeatedImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000734GenerateBuildingCode(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000735 // The code below ensures that the result has an immutable list. If our
736 // list is immutable, we can just reuse it. If not, we make it immutable.
temporal40ee5512008-07-10 02:12:20 +0000737 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000738 "if ($get_mutable_bit_builder$) {\n"
739 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
740 " $clear_mutable_bit_builder$;\n"
741 "}\n"
742 "result.$name$_ = $name$_;\n");
temporal40ee5512008-07-10 02:12:20 +0000743}
744
jieluo@google.com4de8f552014-07-18 00:47:59 +0000745void RepeatedImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000746GenerateParsingCode(io::Printer* printer) const {
kenton@google.comfccb1462009-12-18 02:11:36 +0000747 printer->Print(variables_,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000748 "if (!$get_mutable_bit_parser$) {\n"
749 " $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
750 " $set_mutable_bit_parser$;\n"
751 "}\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000752 "$name$_.add(input.read$capitalized_type$());\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000753}
754
jieluo@google.com4de8f552014-07-18 00:47:59 +0000755void RepeatedImmutablePrimitiveFieldGenerator::
kenton@google.comfccb1462009-12-18 02:11:36 +0000756GenerateParsingCodeFromPacked(io::Printer* printer) const {
757 printer->Print(variables_,
758 "int length = input.readRawVarint32();\n"
759 "int limit = input.pushLimit(length);\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000760 "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
761 " $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
762 " $set_mutable_bit_parser$;\n"
763 "}\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000764 "while (input.getBytesUntilLimit() > 0) {\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000765 " $name$_.add(input.read$capitalized_type$());\n"
kenton@google.comfccb1462009-12-18 02:11:36 +0000766 "}\n"
767 "input.popLimit(limit);\n");
temporal40ee5512008-07-10 02:12:20 +0000768}
769
jieluo@google.com4de8f552014-07-18 00:47:59 +0000770void RepeatedImmutablePrimitiveFieldGenerator::
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000771GenerateParsingDoneCode(io::Printer* printer) const {
772 printer->Print(variables_,
773 "if ($get_mutable_bit_parser$) {\n"
774 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
775 "}\n");
776}
777
jieluo@google.com4de8f552014-07-18 00:47:59 +0000778void RepeatedImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000779GenerateSerializationCode(io::Printer* printer) const {
Bo Yang5db21732015-05-21 14:28:59 -0700780 if (descriptor_->is_packed()) {
Jisi Liu885b6122015-02-28 14:51:22 -0800781 // We invoke getSerializedSize in writeTo for messages that have packed
782 // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods.
783 // That makes it safe to rely on the memoized size here.
kenton@google.com2d6daa72009-01-22 01:27:00 +0000784 printer->Print(variables_,
785 "if (get$capitalized_name$List().size() > 0) {\n"
786 " output.writeRawVarint32($tag$);\n"
787 " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
788 "}\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000789 "for (int i = 0; i < $name$_.size(); i++) {\n"
790 " output.write$capitalized_type$NoTag($name$_.get(i));\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000791 "}\n");
792 } else {
793 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000794 "for (int i = 0; i < $name$_.size(); i++) {\n"
795 " output.write$capitalized_type$($number$, $name$_.get(i));\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000796 "}\n");
797 }
temporal40ee5512008-07-10 02:12:20 +0000798}
799
jieluo@google.com4de8f552014-07-18 00:47:59 +0000800void RepeatedImmutablePrimitiveFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000801GenerateSerializedSizeCode(io::Printer* printer) const {
802 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000803 "{\n"
804 " int dataSize = 0;\n");
805 printer->Indent();
806
kenton@google.comfccb1462009-12-18 02:11:36 +0000807 if (FixedSize(GetType(descriptor_)) == -1) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000808 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000809 "for (int i = 0; i < $name$_.size(); i++) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000810 " dataSize += com.google.protobuf.CodedOutputStream\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000811 " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000812 "}\n");
813 } else {
814 printer->Print(variables_,
815 "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
816 }
817
818 printer->Print(
819 "size += dataSize;\n");
820
Bo Yang5db21732015-05-21 14:28:59 -0700821 if (descriptor_->is_packed()) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000822 printer->Print(variables_,
823 "if (!get$capitalized_name$List().isEmpty()) {\n"
824 " size += $tag_size$;\n"
825 " size += com.google.protobuf.CodedOutputStream\n"
826 " .computeInt32SizeNoTag(dataSize);\n"
827 "}\n");
828 } else {
829 printer->Print(variables_,
830 "size += $tag_size$ * get$capitalized_name$List().size();\n");
831 }
832
833 // cache the data size for packed fields.
Bo Yang5db21732015-05-21 14:28:59 -0700834 if (descriptor_->is_packed()) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000835 printer->Print(variables_,
836 "$name$MemoizedSerializedSize = dataSize;\n");
837 }
838
839 printer->Outdent();
840 printer->Print("}\n");
temporal40ee5512008-07-10 02:12:20 +0000841}
842
jieluo@google.com4de8f552014-07-18 00:47:59 +0000843void RepeatedImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000844GenerateEqualsCode(io::Printer* printer) const {
845 printer->Print(variables_,
846 "result = result && get$capitalized_name$List()\n"
847 " .equals(other.get$capitalized_name$List());\n");
848}
849
jieluo@google.com4de8f552014-07-18 00:47:59 +0000850void RepeatedImmutablePrimitiveFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000851GenerateHashCode(io::Printer* printer) const {
852 printer->Print(variables_,
853 "if (get$capitalized_name$Count() > 0) {\n"
854 " hash = (37 * hash) + $constant_name$;\n"
855 " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
856 "}\n");
857}
858
jieluo@google.com4de8f552014-07-18 00:47:59 +0000859string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const {
temporal40ee5512008-07-10 02:12:20 +0000860 return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
861}
862
863} // namespace java
864} // namespace compiler
865} // namespace protobuf
866} // namespace google