blob: 3e54be3d5a495bfef1bbd1dfdea165d48c992ed9 [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>
42#include <google/protobuf/compiler/java/java_enum_field.h>
temporal40ee5512008-07-10 02:12:20 +000043#include <google/protobuf/compiler/java/java_helpers.h>
jieluo@google.com4de8f552014-07-18 00:47:59 +000044#include <google/protobuf/compiler/java/java_name_resolver.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>
48
49namespace google {
50namespace protobuf {
51namespace compiler {
52namespace java {
53
54namespace {
55
temporal40ee5512008-07-10 02:12:20 +000056void SetEnumVariables(const FieldDescriptor* descriptor,
liujisi@google.com33165fe2010-11-02 13:14:58 +000057 int messageBitIndex,
58 int builderBitIndex,
jieluo@google.com4de8f552014-07-18 00:47:59 +000059 const FieldGeneratorInfo* info,
60 ClassNameResolver* name_resolver,
temporal40ee5512008-07-10 02:12:20 +000061 map<string, string>* variables) {
jieluo@google.com4de8f552014-07-18 00:47:59 +000062 SetCommonFieldVariables(descriptor, info, variables);
63
64 (*variables)["type"] =
65 name_resolver->GetImmutableClassName(descriptor->enum_type());
66 (*variables)["mutable_type"] =
67 name_resolver->GetMutableClassName(descriptor->enum_type());
68 (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
Feng Xiao6ef984a2014-11-10 17:34:54 -080069 (*variables)["default_number"] = SimpleItoa(
70 descriptor->default_value_enum()->number());
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070071 (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
kenton@google.com2d6daa72009-01-22 01:27:00 +000072 (*variables)["tag_size"] = SimpleItoa(
kenton@google.comfccb1462009-12-18 02:11:36 +000073 internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
liujisi@google.com33165fe2010-11-02 13:14:58 +000074 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
75 // by the proto compiler
76 (*variables)["deprecation"] = descriptor->options().deprecated()
77 ? "@java.lang.Deprecated " : "";
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070078 (*variables)["on_changed"] = "onChanged();";
liujisi@google.com33165fe2010-11-02 13:14:58 +000079
jieluo@google.com4de8f552014-07-18 00:47:59 +000080 if (SupportFieldPresence(descriptor->file())) {
81 // For singular messages and builders, one bit is used for the hasField bit.
82 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
83 (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
liujisi@google.com33165fe2010-11-02 13:14:58 +000084
jieluo@google.com4de8f552014-07-18 00:47:59 +000085 // Note that these have a trailing ";".
86 (*variables)["set_has_field_bit_message"] =
87 GenerateSetBit(messageBitIndex) + ";";
88 (*variables)["set_has_field_bit_builder"] =
89 GenerateSetBit(builderBitIndex) + ";";
90 (*variables)["clear_has_field_bit_builder"] =
91 GenerateClearBit(builderBitIndex) + ";";
92
93 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
94 } else {
95 (*variables)["set_has_field_bit_message"] = "";
96 (*variables)["set_has_field_bit_builder"] = "";
97 (*variables)["clear_has_field_bit_builder"] = "";
98
99 (*variables)["is_field_present_message"] =
Feng Xiao6ef984a2014-11-10 17:34:54 -0800100 (*variables)["name"] + "_ != " +
101 (*variables)["default"] + ".getNumber()";
jieluo@google.com4de8f552014-07-18 00:47:59 +0000102 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000103
104 // For repated builders, one bit is used for whether the array is immutable.
105 (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
106 (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
107 (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
108
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000109 // For repeated fields, one bit is used for whether the array is immutable
110 // in the parsing constructor.
111 (*variables)["get_mutable_bit_parser"] =
112 GenerateGetBitMutableLocal(builderBitIndex);
113 (*variables)["set_mutable_bit_parser"] =
114 GenerateSetBitMutableLocal(builderBitIndex);
115
liujisi@google.com33165fe2010-11-02 13:14:58 +0000116 (*variables)["get_has_field_bit_from_local"] =
117 GenerateGetBitFromLocal(builderBitIndex);
118 (*variables)["set_has_field_bit_to_local"] =
119 GenerateSetBitToLocal(messageBitIndex);
Feng Xiao6ef984a2014-11-10 17:34:54 -0800120
121 if (SupportUnknownEnumValue(descriptor->file())) {
122 (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
123 } else {
124 (*variables)["unknown"] = (*variables)["default"];
125 }
temporal40ee5512008-07-10 02:12:20 +0000126}
127
128} // namespace
129
130// ===================================================================
131
jieluo@google.com4de8f552014-07-18 00:47:59 +0000132ImmutableEnumFieldGenerator::
133ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
134 int messageBitIndex,
135 int builderBitIndex,
136 Context* context)
liujisi@google.com33165fe2010-11-02 13:14:58 +0000137 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
jieluo@google.com4de8f552014-07-18 00:47:59 +0000138 builderBitIndex_(builderBitIndex),
139 name_resolver_(context->GetNameResolver()) {
140 SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
141 context->GetFieldGeneratorInfo(descriptor),
142 name_resolver_, &variables_);
temporal40ee5512008-07-10 02:12:20 +0000143}
144
jieluo@google.com4de8f552014-07-18 00:47:59 +0000145ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
temporal40ee5512008-07-10 02:12:20 +0000146
jieluo@google.com4de8f552014-07-18 00:47:59 +0000147int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000148 return 1;
149}
150
jieluo@google.com4de8f552014-07-18 00:47:59 +0000151int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000152 return 1;
153}
154
jieluo@google.com4de8f552014-07-18 00:47:59 +0000155void ImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000156GenerateInterfaceMembers(io::Printer* printer) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000157 if (SupportFieldPresence(descriptor_->file())) {
158 WriteFieldDocComment(printer, descriptor_);
159 printer->Print(variables_,
160 "$deprecation$boolean has$capitalized_name$();\n");
161 }
Feng Xiao6ef984a2014-11-10 17:34:54 -0800162 if (SupportUnknownEnumValue(descriptor_->file())) {
163 WriteFieldDocComment(printer, descriptor_);
164 printer->Print(variables_,
165 "$deprecation$int get$capitalized_name$Value();\n");
166 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000167 WriteFieldDocComment(printer, descriptor_);
168 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000169 "$deprecation$$type$ get$capitalized_name$();\n");
170}
171
jieluo@google.com4de8f552014-07-18 00:47:59 +0000172void ImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000173GenerateMembers(io::Printer* printer) const {
174 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800175 "private int $name$_;\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000176 PrintExtraFieldInfo(variables_, printer);
177 if (SupportFieldPresence(descriptor_->file())) {
178 WriteFieldDocComment(printer, descriptor_);
179 printer->Print(variables_,
180 "$deprecation$public boolean has$capitalized_name$() {\n"
181 " return $get_has_field_bit_message$;\n"
182 "}\n");
183 }
Feng Xiao6ef984a2014-11-10 17:34:54 -0800184 if (SupportUnknownEnumValue(descriptor_->file())) {
185 WriteFieldDocComment(printer, descriptor_);
186 printer->Print(variables_,
187 "$deprecation$public int get$capitalized_name$Value() {\n"
188 " return $name$_;\n"
189 "}\n");
190 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000191 WriteFieldDocComment(printer, descriptor_);
192 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000193 "$deprecation$public $type$ get$capitalized_name$() {\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700194 " $type$ result = $type$.forNumber($name$_);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800195 " return result == null ? $unknown$ : result;\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000196 "}\n");
temporal40ee5512008-07-10 02:12:20 +0000197}
198
jieluo@google.com4de8f552014-07-18 00:47:59 +0000199void ImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000200GenerateBuilderMembers(io::Printer* printer) const {
201 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800202 "private int $name$_ = $default_number$;\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000203 if (SupportFieldPresence(descriptor_->file())) {
204 WriteFieldDocComment(printer, descriptor_);
205 printer->Print(variables_,
206 "$deprecation$public boolean has$capitalized_name$() {\n"
207 " return $get_has_field_bit_builder$;\n"
208 "}\n");
209 }
Feng Xiao6ef984a2014-11-10 17:34:54 -0800210 if (SupportUnknownEnumValue(descriptor_->file())) {
211 WriteFieldDocComment(printer, descriptor_);
212 printer->Print(variables_,
213 "$deprecation$public int get$capitalized_name$Value() {\n"
214 " return $name$_;\n"
215 "}\n");
216 WriteFieldDocComment(printer, descriptor_);
217 printer->Print(variables_,
218 "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
219 " $name$_ = value;\n"
220 " $on_changed$\n"
221 " return this;\n"
222 "}\n");
223 }
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000224 WriteFieldDocComment(printer, descriptor_);
225 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000226 "$deprecation$public $type$ get$capitalized_name$() {\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700227 " $type$ result = $type$.forNumber($name$_);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800228 " return result == null ? $unknown$ : result;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000229 "}\n");
230 WriteFieldDocComment(printer, descriptor_);
231 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000232 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000233 " if (value == null) {\n"
234 " throw new NullPointerException();\n"
235 " }\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000236 " $set_has_field_bit_builder$\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800237 " $name$_ = value.getNumber();\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000238 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000239 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000240 "}\n");
241 WriteFieldDocComment(printer, descriptor_);
242 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000243 "$deprecation$public Builder clear$capitalized_name$() {\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000244 " $clear_has_field_bit_builder$\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800245 " $name$_ = $default_number$;\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000246 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000247 " return this;\n"
248 "}\n");
249}
250
jieluo@google.com4de8f552014-07-18 00:47:59 +0000251void ImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000252GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
253 // noop for enums
254}
255
jieluo@google.com4de8f552014-07-18 00:47:59 +0000256void ImmutableEnumFieldGenerator::
kenton@google.comfccb1462009-12-18 02:11:36 +0000257GenerateInitializationCode(io::Printer* printer) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800258 printer->Print(variables_, "$name$_ = $default_number$;\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000259}
260
jieluo@google.com4de8f552014-07-18 00:47:59 +0000261void ImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000262GenerateBuilderClearCode(io::Printer* printer) const {
263 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800264 "$name$_ = $default_number$;\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000265 "$clear_has_field_bit_builder$\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000266}
267
jieluo@google.com4de8f552014-07-18 00:47:59 +0000268void ImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000269GenerateMergingCode(io::Printer* printer) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000270 if (SupportFieldPresence(descriptor_->file())) {
271 printer->Print(variables_,
272 "if (other.has$capitalized_name$()) {\n"
273 " set$capitalized_name$(other.get$capitalized_name$());\n"
274 "}\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800275 } else if (SupportUnknownEnumValue(descriptor_->file())) {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000276 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800277 "if (other.$name$_ != $default_number$) {\n"
278 " set$capitalized_name$Value(other.get$capitalized_name$Value());\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000279 "}\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800280 } else {
281 GOOGLE_LOG(FATAL) << "Can't reach here.";
jieluo@google.com4de8f552014-07-18 00:47:59 +0000282 }
temporal40ee5512008-07-10 02:12:20 +0000283}
284
jieluo@google.com4de8f552014-07-18 00:47:59 +0000285void ImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000286GenerateBuildingCode(io::Printer* printer) const {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000287 if (SupportFieldPresence(descriptor_->file())) {
288 printer->Print(variables_,
289 "if ($get_has_field_bit_from_local$) {\n"
290 " $set_has_field_bit_to_local$;\n"
291 "}\n");
292 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000293 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000294 "result.$name$_ = $name$_;\n");
temporal40ee5512008-07-10 02:12:20 +0000295}
296
jieluo@google.com4de8f552014-07-18 00:47:59 +0000297void ImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000298GenerateParsingCode(io::Printer* printer) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800299 if (SupportUnknownEnumValue(descriptor_->file())) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000300 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800301 "int rawValue = input.readEnum();\n"
302 "$set_has_field_bit_message$\n"
303 "$name$_ = rawValue;\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000304 } else {
305 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800306 "int rawValue = input.readEnum();\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700307 "$type$ value = $type$.forNumber(rawValue);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800308 "if (value == null) {\n");
309 if (PreserveUnknownFields(descriptor_->containing_type())) {
310 printer->Print(variables_,
311 " unknownFields.mergeVarintField($number$, rawValue);\n");
312 }
313 printer->Print(variables_,
314 "} else {\n"
315 " $set_has_field_bit_message$\n"
316 " $name$_ = rawValue;\n"
317 "}\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000318 }
temporal40ee5512008-07-10 02:12:20 +0000319}
320
jieluo@google.com4de8f552014-07-18 00:47:59 +0000321void ImmutableEnumFieldGenerator::
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000322GenerateParsingDoneCode(io::Printer* printer) const {
323 // noop for enums
324}
325
jieluo@google.com4de8f552014-07-18 00:47:59 +0000326void ImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000327GenerateSerializationCode(io::Printer* printer) const {
328 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000329 "if ($is_field_present_message$) {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800330 " output.writeEnum($number$, $name$_);\n"
temporal40ee5512008-07-10 02:12:20 +0000331 "}\n");
332}
333
jieluo@google.com4de8f552014-07-18 00:47:59 +0000334void ImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000335GenerateSerializedSizeCode(io::Printer* printer) const {
336 printer->Print(variables_,
jieluo@google.com4de8f552014-07-18 00:47:59 +0000337 "if ($is_field_present_message$) {\n"
temporal40ee5512008-07-10 02:12:20 +0000338 " size += com.google.protobuf.CodedOutputStream\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800339 " .computeEnumSize($number$, $name$_);\n"
temporal40ee5512008-07-10 02:12:20 +0000340 "}\n");
341}
342
jieluo@google.com4de8f552014-07-18 00:47:59 +0000343void ImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000344GenerateEqualsCode(io::Printer* printer) const {
345 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800346 "result = result && $name$_ == other.$name$_;\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000347}
348
jieluo@google.com4de8f552014-07-18 00:47:59 +0000349void ImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000350GenerateHashCode(io::Printer* printer) const {
351 printer->Print(variables_,
352 "hash = (37 * hash) + $constant_name$;\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800353 "hash = (53 * hash) + $name$_;\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000354}
355
jieluo@google.com4de8f552014-07-18 00:47:59 +0000356string ImmutableEnumFieldGenerator::GetBoxedType() const {
357 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
temporal40ee5512008-07-10 02:12:20 +0000358}
359
360// ===================================================================
361
jieluo@google.com4de8f552014-07-18 00:47:59 +0000362ImmutableEnumOneofFieldGenerator::
363ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor,
364 int messageBitIndex,
365 int builderBitIndex,
366 Context* context)
367 : ImmutableEnumFieldGenerator(
368 descriptor, messageBitIndex, builderBitIndex, context) {
369 const OneofGeneratorInfo* info =
370 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
371 SetCommonOneofVariables(descriptor, info, &variables_);
temporal40ee5512008-07-10 02:12:20 +0000372}
373
jieluo@google.com4de8f552014-07-18 00:47:59 +0000374ImmutableEnumOneofFieldGenerator::
375~ImmutableEnumOneofFieldGenerator() {}
temporal40ee5512008-07-10 02:12:20 +0000376
jieluo@google.com4de8f552014-07-18 00:47:59 +0000377void ImmutableEnumOneofFieldGenerator::
378GenerateMembers(io::Printer* printer) const {
379 PrintExtraFieldInfo(variables_, printer);
380 if (SupportFieldPresence(descriptor_->file())) {
381 WriteFieldDocComment(printer, descriptor_);
382 printer->Print(variables_,
383 "$deprecation$public boolean has$capitalized_name$() {\n"
384 " return $has_oneof_case_message$;\n"
385 "}\n");
386 }
Feng Xiao6ef984a2014-11-10 17:34:54 -0800387 if (SupportUnknownEnumValue(descriptor_->file())) {
388 WriteFieldDocComment(printer, descriptor_);
389 printer->Print(variables_,
390 "$deprecation$public int get$capitalized_name$Value() {\n"
391 " if ($has_oneof_case_message$) {\n"
392 " return (java.lang.Integer) $oneof_name$_;\n"
393 " }\n"
394 " return $default_number$;\n"
395 "}\n");
396 }
jieluo@google.com4de8f552014-07-18 00:47:59 +0000397 WriteFieldDocComment(printer, descriptor_);
398 printer->Print(variables_,
399 "$deprecation$public $type$ get$capitalized_name$() {\n"
400 " if ($has_oneof_case_message$) {\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700401 " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800402 " return result == null ? $unknown$ : result;\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000403 " }\n"
404 " return $default$;\n"
405 "}\n");
406}
407
408void ImmutableEnumOneofFieldGenerator::
409GenerateBuilderMembers(io::Printer* printer) const {
410 if (SupportFieldPresence(descriptor_->file())) {
411 WriteFieldDocComment(printer, descriptor_);
412 printer->Print(variables_,
413 "$deprecation$public boolean has$capitalized_name$() {\n"
414 " return $has_oneof_case_message$;\n"
415 "}\n");
416 }
Feng Xiao6ef984a2014-11-10 17:34:54 -0800417 if (SupportUnknownEnumValue(descriptor_->file())) {
418 WriteFieldDocComment(printer, descriptor_);
419 printer->Print(variables_,
420 "$deprecation$public int get$capitalized_name$Value() {\n"
421 " if ($has_oneof_case_message$) {\n"
422 " return ((java.lang.Integer) $oneof_name$_).intValue();\n"
423 " }\n"
424 " return $default_number$;\n"
425 "}\n");
426 WriteFieldDocComment(printer, descriptor_);
427 printer->Print(variables_,
428 "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
429 " $set_oneof_case_message$;\n"
430 " $oneof_name$_ = value;\n"
431 " $on_changed$\n"
432 " return this;\n"
433 "}\n");
434 }
jieluo@google.com4de8f552014-07-18 00:47:59 +0000435 WriteFieldDocComment(printer, descriptor_);
436 printer->Print(variables_,
437 "$deprecation$public $type$ get$capitalized_name$() {\n"
438 " if ($has_oneof_case_message$) {\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700439 " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800440 " return result == null ? $unknown$ : result;\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000441 " }\n"
442 " return $default$;\n"
443 "}\n");
444 WriteFieldDocComment(printer, descriptor_);
445 printer->Print(variables_,
446 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
447 " if (value == null) {\n"
448 " throw new NullPointerException();\n"
449 " }\n"
450 " $set_oneof_case_message$;\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800451 " $oneof_name$_ = value.getNumber();\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000452 " $on_changed$\n"
453 " return this;\n"
454 "}\n");
455 WriteFieldDocComment(printer, descriptor_);
456 printer->Print(variables_,
457 "$deprecation$public Builder clear$capitalized_name$() {\n"
458 " if ($has_oneof_case_message$) {\n"
459 " $clear_oneof_case_message$;\n"
460 " $oneof_name$_ = null;\n"
461 " $on_changed$\n"
462 " }\n"
463 " return this;\n"
464 "}\n");
465}
466
467void ImmutableEnumOneofFieldGenerator::
468GenerateBuildingCode(io::Printer* printer) const {
469 printer->Print(variables_,
470 "if ($has_oneof_case_message$) {\n"
471 " result.$oneof_name$_ = $oneof_name$_;\n"
472 "}\n");
473}
474
475void ImmutableEnumOneofFieldGenerator::
476GenerateMergingCode(io::Printer* printer) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800477 if (SupportUnknownEnumValue(descriptor_->file())) {
478 printer->Print(variables_,
479 "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
480 } else {
481 printer->Print(variables_,
482 "set$capitalized_name$(other.get$capitalized_name$());\n");
483 }
jieluo@google.com4de8f552014-07-18 00:47:59 +0000484}
485
486void ImmutableEnumOneofFieldGenerator::
487GenerateParsingCode(io::Printer* printer) const {
Feng Xiao6ef984a2014-11-10 17:34:54 -0800488 if (SupportUnknownEnumValue(descriptor_->file())) {
jieluo@google.com4de8f552014-07-18 00:47:59 +0000489 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800490 "int rawValue = input.readEnum();\n"
491 "$set_oneof_case_message$;\n"
492 "$oneof_name$_ = rawValue;\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000493 } else {
494 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800495 "int rawValue = input.readEnum();\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700496 "$type$ value = $type$.forNumber(rawValue);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800497 "if (value == null) {\n");
498 if (PreserveUnknownFields(descriptor_->containing_type())) {
499 printer->Print(variables_,
500 " unknownFields.mergeVarintField($number$, rawValue);\n");
501 }
502 printer->Print(variables_,
503 "} else {\n"
504 " $set_oneof_case_message$;\n"
505 " $oneof_name$_ = rawValue;\n"
506 "}\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000507 }
jieluo@google.com4de8f552014-07-18 00:47:59 +0000508}
509
510void ImmutableEnumOneofFieldGenerator::
511GenerateSerializationCode(io::Printer* printer) const {
512 printer->Print(variables_,
513 "if ($has_oneof_case_message$) {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800514 " output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000515 "}\n");
516}
517
518void ImmutableEnumOneofFieldGenerator::
519GenerateSerializedSizeCode(io::Printer* printer) const {
520 printer->Print(variables_,
521 "if ($has_oneof_case_message$) {\n"
522 " size += com.google.protobuf.CodedOutputStream\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800523 " .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
jieluo@google.com4de8f552014-07-18 00:47:59 +0000524 "}\n");
525}
526
Feng Xiao6ef984a2014-11-10 17:34:54 -0800527void ImmutableEnumOneofFieldGenerator::
528GenerateEqualsCode(io::Printer* printer) const {
529 if (SupportUnknownEnumValue(descriptor_->file())) {
530 printer->Print(variables_,
531 "result = result && get$capitalized_name$Value()\n"
532 " == other.get$capitalized_name$Value();\n");
533 } else {
534 printer->Print(variables_,
535 "result = result && get$capitalized_name$()\n"
536 " .equals(other.get$capitalized_name$());\n");
537 }
538}
539
540void ImmutableEnumOneofFieldGenerator::
541GenerateHashCode(io::Printer* printer) const {
542 if (SupportUnknownEnumValue(descriptor_->file())) {
543 printer->Print(variables_,
544 "hash = (37 * hash) + $constant_name$;\n"
545 "hash = (53 * hash) + get$capitalized_name$Value();\n");
546 } else {
547 printer->Print(variables_,
548 "hash = (37 * hash) + $constant_name$;\n"
549 "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
550 }
551}
552
jieluo@google.com4de8f552014-07-18 00:47:59 +0000553// ===================================================================
554
555RepeatedImmutableEnumFieldGenerator::
556RepeatedImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
557 int messageBitIndex,
558 int builderBitIndex,
559 Context* context)
560 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
561 builderBitIndex_(builderBitIndex), context_(context),
562 name_resolver_(context->GetNameResolver()) {
563 SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
564 context->GetFieldGeneratorInfo(descriptor),
565 name_resolver_, &variables_);
566}
567
568RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
569
570int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000571 return 0;
572}
573
jieluo@google.com4de8f552014-07-18 00:47:59 +0000574int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000575 return 1;
576}
577
jieluo@google.com4de8f552014-07-18 00:47:59 +0000578void RepeatedImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000579GenerateInterfaceMembers(io::Printer* printer) const {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000580 WriteFieldDocComment(printer, descriptor_);
liujisi@google.com33165fe2010-11-02 13:14:58 +0000581 printer->Print(variables_,
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000582 "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
583 WriteFieldDocComment(printer, descriptor_);
584 printer->Print(variables_,
585 "$deprecation$int get$capitalized_name$Count();\n");
586 WriteFieldDocComment(printer, descriptor_);
587 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000588 "$deprecation$$type$ get$capitalized_name$(int index);\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800589 if (SupportUnknownEnumValue(descriptor_->file())) {
590 WriteFieldDocComment(printer, descriptor_);
591 printer->Print(variables_,
592 "$deprecation$java.util.List<java.lang.Integer>\n"
593 "get$capitalized_name$ValueList();\n");
594 WriteFieldDocComment(printer, descriptor_);
595 printer->Print(variables_,
596 "$deprecation$int get$capitalized_name$Value(int index);\n");
597 }
liujisi@google.com33165fe2010-11-02 13:14:58 +0000598}
599
jieluo@google.com4de8f552014-07-18 00:47:59 +0000600void RepeatedImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000601GenerateMembers(io::Printer* printer) const {
602 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800603 "private java.util.List<java.lang.Integer> $name$_;\n"
604 "private static final com.google.protobuf.Internal.ListAdapter.Converter<\n"
605 " java.lang.Integer, $type$> $name$_converter_ =\n"
606 " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
607 " java.lang.Integer, $type$>() {\n"
608 " public $type$ convert(java.lang.Integer from) {\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700609 " $type$ result = $type$.forNumber(from);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800610 " return result == null ? $unknown$ : result;\n"
611 " }\n"
612 " };\n");
jieluo@google.com4de8f552014-07-18 00:47:59 +0000613 PrintExtraFieldInfo(variables_, printer);
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000614 WriteFieldDocComment(printer, descriptor_);
615 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000616 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800617 " return new com.google.protobuf.Internal.ListAdapter<\n"
618 " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000619 "}\n");
620 WriteFieldDocComment(printer, descriptor_);
621 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000622 "$deprecation$public int get$capitalized_name$Count() {\n"
623 " return $name$_.size();\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000624 "}\n");
625 WriteFieldDocComment(printer, descriptor_);
626 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000627 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800628 " return $name$_converter_.convert($name$_.get(index));\n"
temporal40ee5512008-07-10 02:12:20 +0000629 "}\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800630 if (SupportUnknownEnumValue(descriptor_->file())) {
631 WriteFieldDocComment(printer, descriptor_);
632 printer->Print(variables_,
633 "$deprecation$public java.util.List<java.lang.Integer>\n"
634 "get$capitalized_name$ValueList() {\n"
635 " return $name$_;\n"
636 "}\n");
637 WriteFieldDocComment(printer, descriptor_);
638 printer->Print(variables_,
639 "$deprecation$public int get$capitalized_name$Value(int index) {\n"
640 " return $name$_.get(index);\n"
641 "}\n");
642 }
kenton@google.com2d6daa72009-01-22 01:27:00 +0000643
Bo Yang5db21732015-05-21 14:28:59 -0700644 if (descriptor_->is_packed() &&
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700645 context_->HasGeneratedMethods(descriptor_->containing_type())) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000646 printer->Print(variables_,
647 "private int $name$MemoizedSerializedSize;\n");
648 }
temporal40ee5512008-07-10 02:12:20 +0000649}
650
jieluo@google.com4de8f552014-07-18 00:47:59 +0000651void RepeatedImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000652GenerateBuilderMembers(io::Printer* printer) const {
653 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000654 // One field is the list and the other field keeps track of whether the
655 // list is immutable. If it's immutable, the invariant is that it must
656 // either an instance of Collections.emptyList() or it's an ArrayList
657 // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
658 // a refererence to the underlying ArrayList. This invariant allows us to
659 // share instances of lists between protocol buffers avoiding expensive
660 // memory allocations. Note, immutable is a strong guarantee here -- not
661 // just that the list cannot be modified via the reference but that the
662 // list can never be modified.
Feng Xiao6ef984a2014-11-10 17:34:54 -0800663 "private java.util.List<java.lang.Integer> $name$_ =\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000664 " java.util.Collections.emptyList();\n"
665
666 "private void ensure$capitalized_name$IsMutable() {\n"
667 " if (!$get_mutable_bit_builder$) {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800668 " $name$_ = new java.util.ArrayList<java.lang.Integer>($name$_);\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000669 " $set_mutable_bit_builder$;\n"
670 " }\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000671 "}\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000672
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000673 WriteFieldDocComment(printer, descriptor_);
674 printer->Print(variables_,
temporal40ee5512008-07-10 02:12:20 +0000675 // Note: We return an unmodifiable list because otherwise the caller
676 // could hold on to the returned list and modify it after the message
677 // has been built, thus mutating the message which is supposed to be
678 // immutable.
liujisi@google.com33165fe2010-11-02 13:14:58 +0000679 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800680 " return new com.google.protobuf.Internal.ListAdapter<\n"
681 " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000682 "}\n");
683 WriteFieldDocComment(printer, descriptor_);
684 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000685 "$deprecation$public int get$capitalized_name$Count() {\n"
686 " return $name$_.size();\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000687 "}\n");
688 WriteFieldDocComment(printer, descriptor_);
689 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000690 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800691 " return $name$_converter_.convert($name$_.get(index));\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000692 "}\n");
693 WriteFieldDocComment(printer, descriptor_);
694 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000695 "$deprecation$public Builder set$capitalized_name$(\n"
696 " int index, $type$ value) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000697 " if (value == null) {\n"
698 " throw new NullPointerException();\n"
699 " }\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000700 " ensure$capitalized_name$IsMutable();\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800701 " $name$_.set(index, value.getNumber());\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000702 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000703 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000704 "}\n");
705 WriteFieldDocComment(printer, descriptor_);
706 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000707 "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000708 " if (value == null) {\n"
709 " throw new NullPointerException();\n"
710 " }\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000711 " ensure$capitalized_name$IsMutable();\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800712 " $name$_.add(value.getNumber());\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000713 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000714 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000715 "}\n");
716 WriteFieldDocComment(printer, descriptor_);
717 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000718 "$deprecation$public Builder addAll$capitalized_name$(\n"
temporal40ee5512008-07-10 02:12:20 +0000719 " java.lang.Iterable<? extends $type$> values) {\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000720 " ensure$capitalized_name$IsMutable();\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800721 " for ($type$ value : values) {\n"
722 " $name$_.add(value.getNumber());\n"
723 " }\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000724 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000725 " return this;\n"
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000726 "}\n");
727 WriteFieldDocComment(printer, descriptor_);
728 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000729 "$deprecation$public Builder clear$capitalized_name$() {\n"
730 " $name$_ = java.util.Collections.emptyList();\n"
731 " $clear_mutable_bit_builder$;\n"
732 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000733 " return this;\n"
734 "}\n");
Feng Xiao6ef984a2014-11-10 17:34:54 -0800735
736 if (SupportUnknownEnumValue(descriptor_->file())) {
737 WriteFieldDocComment(printer, descriptor_);
738 printer->Print(variables_,
739 "$deprecation$public java.util.List<java.lang.Integer>\n"
740 "get$capitalized_name$ValueList() {\n"
741 " return java.util.Collections.unmodifiableList($name$_);\n"
742 "}\n");
743 WriteFieldDocComment(printer, descriptor_);
744 printer->Print(variables_,
745 "$deprecation$public int get$capitalized_name$Value(int index) {\n"
746 " return $name$_.get(index);\n"
747 "}\n");
748 WriteFieldDocComment(printer, descriptor_);
749 printer->Print(variables_,
750 "$deprecation$public Builder set$capitalized_name$Value(\n"
751 " int index, int value) {\n"
752 " ensure$capitalized_name$IsMutable();\n"
753 " $name$_.set(index, value);\n"
754 " $on_changed$\n"
755 " return this;\n"
756 "}\n");
757 WriteFieldDocComment(printer, descriptor_);
758 printer->Print(variables_,
759 "$deprecation$public Builder add$capitalized_name$Value(int value) {\n"
760 " ensure$capitalized_name$IsMutable();\n"
761 " $name$_.add(value);\n"
762 " $on_changed$\n"
763 " return this;\n"
764 "}\n");
765 WriteFieldDocComment(printer, descriptor_);
766 printer->Print(variables_,
767 "$deprecation$public Builder addAll$capitalized_name$Value(\n"
768 " java.lang.Iterable<java.lang.Integer> values) {\n"
769 " ensure$capitalized_name$IsMutable();\n"
770 " for (int value : values) {\n"
771 " $name$_.add(value);\n"
772 " }\n"
773 " $on_changed$\n"
774 " return this;\n"
775 "}\n");
776 }
temporal40ee5512008-07-10 02:12:20 +0000777}
778
jieluo@google.com4de8f552014-07-18 00:47:59 +0000779void RepeatedImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000780GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
781 // noop for enums
782}
783
jieluo@google.com4de8f552014-07-18 00:47:59 +0000784void RepeatedImmutableEnumFieldGenerator::
kenton@google.comfccb1462009-12-18 02:11:36 +0000785GenerateInitializationCode(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000786 printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
787}
788
jieluo@google.com4de8f552014-07-18 00:47:59 +0000789void RepeatedImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000790GenerateBuilderClearCode(io::Printer* printer) const {
791 printer->Print(variables_,
792 "$name$_ = java.util.Collections.emptyList();\n"
793 "$clear_mutable_bit_builder$;\n");
kenton@google.comfccb1462009-12-18 02:11:36 +0000794}
795
jieluo@google.com4de8f552014-07-18 00:47:59 +0000796void RepeatedImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000797GenerateMergingCode(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000798 // The code below does two optimizations:
799 // 1. If the other list is empty, there's nothing to do. This ensures we
800 // don't allocate a new array if we already have an immutable one.
801 // 2. If the other list is non-empty and our current list is empty, we can
802 // reuse the other list which is guaranteed to be immutable.
temporal40ee5512008-07-10 02:12:20 +0000803 printer->Print(variables_,
804 "if (!other.$name$_.isEmpty()) {\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000805 " if ($name$_.isEmpty()) {\n"
806 " $name$_ = other.$name$_;\n"
807 " $clear_mutable_bit_builder$;\n"
808 " } else {\n"
809 " ensure$capitalized_name$IsMutable();\n"
810 " $name$_.addAll(other.$name$_);\n"
temporal40ee5512008-07-10 02:12:20 +0000811 " }\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000812 " $on_changed$\n"
temporal40ee5512008-07-10 02:12:20 +0000813 "}\n");
814}
815
jieluo@google.com4de8f552014-07-18 00:47:59 +0000816void RepeatedImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000817GenerateBuildingCode(io::Printer* printer) const {
liujisi@google.com33165fe2010-11-02 13:14:58 +0000818 // The code below ensures that the result has an immutable list. If our
819 // list is immutable, we can just reuse it. If not, we make it immutable.
temporal40ee5512008-07-10 02:12:20 +0000820 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000821 "if ($get_mutable_bit_builder$) {\n"
822 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
823 " $clear_mutable_bit_builder$;\n"
824 "}\n"
825 "result.$name$_ = $name$_;\n");
temporal40ee5512008-07-10 02:12:20 +0000826}
827
jieluo@google.com4de8f552014-07-18 00:47:59 +0000828void RepeatedImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000829GenerateParsingCode(io::Printer* printer) const {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000830 // Read and store the enum
Feng Xiao6ef984a2014-11-10 17:34:54 -0800831 if (SupportUnknownEnumValue(descriptor_->file())) {
kenton@google.com80b1d622009-07-29 01:13:20 +0000832 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800833 "int rawValue = input.readEnum();\n"
834 "if (!$get_mutable_bit_parser$) {\n"
835 " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
836 " $set_mutable_bit_parser$;\n"
837 "}\n"
838 "$name$_.add(rawValue);\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000839 } else {
840 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800841 "int rawValue = input.readEnum();\n"
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700842 "$type$ value = $type$.forNumber(rawValue);\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800843 "if (value == null) {\n");
844 if (PreserveUnknownFields(descriptor_->containing_type())) {
845 printer->Print(variables_,
846 " unknownFields.mergeVarintField($number$, rawValue);\n");
847 }
848 printer->Print(variables_,
849 "} else {\n"
850 " if (!$get_mutable_bit_parser$) {\n"
851 " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
852 " $set_mutable_bit_parser$;\n"
853 " }\n"
854 " $name$_.add(rawValue);\n"
855 "}\n");
kenton@google.com80b1d622009-07-29 01:13:20 +0000856 }
kenton@google.comfccb1462009-12-18 02:11:36 +0000857}
kenton@google.com2d6daa72009-01-22 01:27:00 +0000858
jieluo@google.com4de8f552014-07-18 00:47:59 +0000859void RepeatedImmutableEnumFieldGenerator::
kenton@google.comfccb1462009-12-18 02:11:36 +0000860GenerateParsingCodeFromPacked(io::Printer* printer) const {
861 // Wrap GenerateParsingCode's contents with a while loop.
862
863 printer->Print(variables_,
864 "int length = input.readRawVarint32();\n"
865 "int oldLimit = input.pushLimit(length);\n"
866 "while(input.getBytesUntilLimit() > 0) {\n");
867 printer->Indent();
868
869 GenerateParsingCode(printer);
870
871 printer->Outdent();
872 printer->Print(variables_,
873 "}\n"
874 "input.popLimit(oldLimit);\n");
temporal40ee5512008-07-10 02:12:20 +0000875}
876
jieluo@google.com4de8f552014-07-18 00:47:59 +0000877void RepeatedImmutableEnumFieldGenerator::
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000878GenerateParsingDoneCode(io::Printer* printer) const {
879 printer->Print(variables_,
880 "if ($get_mutable_bit_parser$) {\n"
881 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
882 "}\n");
883}
884
jieluo@google.com4de8f552014-07-18 00:47:59 +0000885void RepeatedImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000886GenerateSerializationCode(io::Printer* printer) const {
Bo Yang5db21732015-05-21 14:28:59 -0700887 if (descriptor_->is_packed()) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000888 printer->Print(variables_,
889 "if (get$capitalized_name$List().size() > 0) {\n"
890 " output.writeRawVarint32($tag$);\n"
891 " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
892 "}\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000893 "for (int i = 0; i < $name$_.size(); i++) {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800894 " output.writeEnumNoTag($name$_.get(i));\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000895 "}\n");
896 } else {
897 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000898 "for (int i = 0; i < $name$_.size(); i++) {\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800899 " output.writeEnum($number$, $name$_.get(i));\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000900 "}\n");
901 }
temporal40ee5512008-07-10 02:12:20 +0000902}
903
jieluo@google.com4de8f552014-07-18 00:47:59 +0000904void RepeatedImmutableEnumFieldGenerator::
temporal40ee5512008-07-10 02:12:20 +0000905GenerateSerializedSizeCode(io::Printer* printer) const {
906 printer->Print(variables_,
kenton@google.com2d6daa72009-01-22 01:27:00 +0000907 "{\n"
908 " int dataSize = 0;\n");
909 printer->Indent();
910
911 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000912 "for (int i = 0; i < $name$_.size(); i++) {\n"
kenton@google.com2d6daa72009-01-22 01:27:00 +0000913 " dataSize += com.google.protobuf.CodedOutputStream\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800914 " .computeEnumSizeNoTag($name$_.get(i));\n"
temporal40ee5512008-07-10 02:12:20 +0000915 "}\n");
kenton@google.com2d6daa72009-01-22 01:27:00 +0000916 printer->Print(
917 "size += dataSize;\n");
Bo Yang5db21732015-05-21 14:28:59 -0700918 if (descriptor_->is_packed()) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000919 printer->Print(variables_,
920 "if (!get$capitalized_name$List().isEmpty()) {"
921 " size += $tag_size$;\n"
922 " size += com.google.protobuf.CodedOutputStream\n"
923 " .computeRawVarint32Size(dataSize);\n"
924 "}");
925 } else {
926 printer->Print(variables_,
liujisi@google.com33165fe2010-11-02 13:14:58 +0000927 "size += $tag_size$ * $name$_.size();\n");
kenton@google.com2d6daa72009-01-22 01:27:00 +0000928 }
929
930 // cache the data size for packed fields.
Bo Yang5db21732015-05-21 14:28:59 -0700931 if (descriptor_->is_packed()) {
kenton@google.com2d6daa72009-01-22 01:27:00 +0000932 printer->Print(variables_,
933 "$name$MemoizedSerializedSize = dataSize;\n");
934 }
935
936 printer->Outdent();
937 printer->Print("}\n");
temporal40ee5512008-07-10 02:12:20 +0000938}
939
jieluo@google.com4de8f552014-07-18 00:47:59 +0000940void RepeatedImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000941GenerateEqualsCode(io::Printer* printer) const {
942 printer->Print(variables_,
Feng Xiao6ef984a2014-11-10 17:34:54 -0800943 "result = result && $name$_.equals(other.$name$_);\n");
liujisi@google.com33165fe2010-11-02 13:14:58 +0000944}
945
jieluo@google.com4de8f552014-07-18 00:47:59 +0000946void RepeatedImmutableEnumFieldGenerator::
liujisi@google.com33165fe2010-11-02 13:14:58 +0000947GenerateHashCode(io::Printer* printer) const {
948 printer->Print(variables_,
949 "if (get$capitalized_name$Count() > 0) {\n"
950 " hash = (37 * hash) + $constant_name$;\n"
Feng Xiao6ef984a2014-11-10 17:34:54 -0800951 " hash = (53 * hash) + $name$_.hashCode();\n"
liujisi@google.com33165fe2010-11-02 13:14:58 +0000952 "}\n");
953}
954
jieluo@google.com4de8f552014-07-18 00:47:59 +0000955string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
956 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
temporal40ee5512008-07-10 02:12:20 +0000957}
958
959} // namespace java
960} // namespace compiler
961} // namespace protobuf
962} // namespace google