Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 :
35 : #include <map>
36 : #include <string>
37 :
38 : #include <google/protobuf/stubs/logging.h>
39 : #include <google/protobuf/stubs/common.h>
40 : #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_helpers.h>
43 : #include <google/protobuf/compiler/java/java_name_resolver.h>
44 : #include <google/protobuf/compiler/java/java_primitive_field_lite.h>
45 : #include <google/protobuf/io/printer.h>
46 : #include <google/protobuf/wire_format.h>
47 : #include <google/protobuf/stubs/strutil.h>
48 :
49 : namespace google {
50 : namespace protobuf {
51 : namespace compiler {
52 : namespace java {
53 :
54 : using internal::WireFormat;
55 : using internal::WireFormatLite;
56 :
57 : namespace {
58 :
59 0 : void SetPrimitiveVariables(const FieldDescriptor* descriptor,
60 : int messageBitIndex,
61 : int builderBitIndex,
62 : const FieldGeneratorInfo* info,
63 : ClassNameResolver* name_resolver,
64 : map<string, string>* variables) {
65 0 : SetCommonFieldVariables(descriptor, info, variables);
66 :
67 0 : (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
68 0 : (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
69 0 : (*variables)["field_type"] = (*variables)["type"];
70 0 : (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
71 0 : (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
72 0 : "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
73 0 : (*variables)["capitalized_type"] =
74 : GetCapitalizedType(descriptor, /* immutable = */ true);
75 0 : (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
76 0 : (*variables)["tag_size"] = SimpleItoa(
77 : WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
78 :
79 : string capitalized_type = UnderscoresToCamelCase(PrimitiveTypeName(
80 0 : GetJavaType(descriptor)), true /* cap_next_letter */);
81 0 : switch (GetJavaType(descriptor)) {
82 : case JAVATYPE_INT:
83 : case JAVATYPE_LONG:
84 : case JAVATYPE_FLOAT:
85 : case JAVATYPE_DOUBLE:
86 : case JAVATYPE_BOOLEAN:
87 0 : (*variables)["field_list_type"] =
88 0 : "com.google.protobuf.Internal." + capitalized_type + "List";
89 0 : (*variables)["new_list"] = "new" + capitalized_type + "List";
90 0 : (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
91 0 : (*variables)["make_name_unmodifiable"] =
92 0 : (*variables)["name"] + "_.makeImmutable()";
93 0 : (*variables)["repeated_index_get"] =
94 0 : (*variables)["name"] + "_.get" + capitalized_type + "(index)";
95 0 : (*variables)["repeated_add"] =
96 0 : (*variables)["name"] + "_.add" + capitalized_type;
97 0 : (*variables)["repeated_set"] =
98 0 : (*variables)["name"] + "_.set" + capitalized_type;
99 0 : break;
100 : default:
101 0 : (*variables)["field_list_type"] =
102 0 : "com.google.protobuf.Internal.ProtobufList<" +
103 0 : (*variables)["boxed_type"] + ">";
104 0 : (*variables)["new_list"] = "newProtobufList";
105 0 : (*variables)["empty_list"] = "emptyProtobufList()";
106 0 : (*variables)["make_name_unmodifiable"] =
107 0 : (*variables)["name"] + "_.makeImmutable()";
108 0 : (*variables)["repeated_index_get"] =
109 0 : (*variables)["name"] + "_.get(index)";
110 0 : (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
111 0 : (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
112 : }
113 :
114 0 : if (IsReferenceType(GetJavaType(descriptor))) {
115 0 : (*variables)["null_check"] =
116 : " if (value == null) {\n"
117 : " throw new NullPointerException();\n"
118 : " }\n";
119 : } else {
120 0 : (*variables)["null_check"] = "";
121 : }
122 : // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
123 : // by the proto compiler
124 0 : (*variables)["deprecation"] = descriptor->options().deprecated()
125 : ? "@java.lang.Deprecated " : "";
126 0 : int fixed_size = FixedSize(GetType(descriptor));
127 0 : if (fixed_size != -1) {
128 0 : (*variables)["fixed_size"] = SimpleItoa(fixed_size);
129 : }
130 0 : (*variables)["on_changed"] =
131 0 : HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
132 :
133 0 : if (SupportFieldPresence(descriptor->file())) {
134 : // For singular messages and builders, one bit is used for the hasField bit.
135 0 : (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
136 :
137 : // Note that these have a trailing ";".
138 0 : (*variables)["set_has_field_bit_message"] =
139 0 : GenerateSetBit(messageBitIndex) + ";";
140 0 : (*variables)["clear_has_field_bit_message"] =
141 0 : GenerateClearBit(messageBitIndex) + ";";
142 :
143 0 : (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
144 : } else {
145 0 : (*variables)["set_has_field_bit_message"] = "";
146 0 : (*variables)["set_has_field_bit_message"] = "";
147 0 : (*variables)["clear_has_field_bit_message"] = "";
148 :
149 0 : if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
150 0 : (*variables)["is_field_present_message"] =
151 0 : "!" + (*variables)["name"] + "_.isEmpty()";
152 : } else {
153 0 : (*variables)["is_field_present_message"] =
154 0 : (*variables)["name"] + "_ != " + (*variables)["default"];
155 : }
156 : }
157 :
158 : // For repeated builders, the underlying list tracks mutability state.
159 0 : (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
160 :
161 0 : (*variables)["get_has_field_bit_from_local"] =
162 : GenerateGetBitFromLocal(builderBitIndex);
163 0 : (*variables)["set_has_field_bit_to_local"] =
164 : GenerateSetBitToLocal(messageBitIndex);
165 0 : }
166 :
167 : } // namespace
168 :
169 : // ===================================================================
170 :
171 0 : ImmutablePrimitiveFieldLiteGenerator::
172 : ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor* descriptor,
173 : int messageBitIndex,
174 : int builderBitIndex,
175 : Context* context)
176 : : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
177 : builderBitIndex_(builderBitIndex), context_(context),
178 0 : name_resolver_(context->GetNameResolver()) {
179 : SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
180 : context->GetFieldGeneratorInfo(descriptor),
181 0 : name_resolver_, &variables_);
182 0 : }
183 :
184 0 : ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
185 :
186 0 : int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
187 0 : return 1;
188 : }
189 :
190 0 : int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForBuilder() const {
191 0 : return 0;
192 : }
193 :
194 0 : void ImmutablePrimitiveFieldLiteGenerator::
195 : GenerateInterfaceMembers(io::Printer* printer) const {
196 0 : if (SupportFieldPresence(descriptor_->file())) {
197 0 : WriteFieldDocComment(printer, descriptor_);
198 : printer->Print(variables_,
199 0 : "$deprecation$boolean has$capitalized_name$();\n");
200 : }
201 0 : WriteFieldDocComment(printer, descriptor_);
202 : printer->Print(variables_,
203 0 : "$deprecation$$type$ get$capitalized_name$();\n");
204 0 : }
205 :
206 0 : void ImmutablePrimitiveFieldLiteGenerator::
207 : GenerateMembers(io::Printer* printer) const {
208 : printer->Print(variables_,
209 0 : "private $field_type$ $name$_;\n");
210 0 : PrintExtraFieldInfo(variables_, printer);
211 0 : if (SupportFieldPresence(descriptor_->file())) {
212 0 : WriteFieldDocComment(printer, descriptor_);
213 : printer->Print(variables_,
214 : "$deprecation$public boolean has$capitalized_name$() {\n"
215 : " return $get_has_field_bit_message$;\n"
216 0 : "}\n");
217 : }
218 :
219 0 : WriteFieldDocComment(printer, descriptor_);
220 : printer->Print(variables_,
221 : "$deprecation$public $type$ get$capitalized_name$() {\n"
222 : " return $name$_;\n"
223 0 : "}\n");
224 :
225 0 : WriteFieldDocComment(printer, descriptor_);
226 : printer->Print(variables_,
227 : "private void set$capitalized_name$($type$ value) {\n"
228 : "$null_check$"
229 : " $set_has_field_bit_message$\n"
230 : " $name$_ = value;\n"
231 0 : "}\n");
232 :
233 0 : WriteFieldDocComment(printer, descriptor_);
234 : printer->Print(variables_,
235 : "private void clear$capitalized_name$() {\n"
236 0 : " $clear_has_field_bit_message$\n");
237 0 : JavaType type = GetJavaType(descriptor_);
238 0 : if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
239 : // The default value is not a simple literal so we want to avoid executing
240 : // it multiple times. Instead, get the default out of the default instance.
241 : printer->Print(variables_,
242 0 : " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
243 : } else {
244 : printer->Print(variables_,
245 0 : " $name$_ = $default$;\n");
246 : }
247 : printer->Print(variables_,
248 0 : "}\n");
249 0 : }
250 :
251 0 : void ImmutablePrimitiveFieldLiteGenerator::
252 : GenerateBuilderMembers(io::Printer* printer) const {
253 0 : if (SupportFieldPresence(descriptor_->file())) {
254 0 : WriteFieldDocComment(printer, descriptor_);
255 : printer->Print(variables_,
256 : "$deprecation$public boolean has$capitalized_name$() {\n"
257 : " return instance.has$capitalized_name$();\n"
258 0 : "}\n");
259 : }
260 :
261 0 : WriteFieldDocComment(printer, descriptor_);
262 : printer->Print(variables_,
263 : "$deprecation$public $type$ get$capitalized_name$() {\n"
264 : " return instance.get$capitalized_name$();\n"
265 0 : "}\n");
266 :
267 0 : WriteFieldDocComment(printer, descriptor_);
268 : printer->Print(variables_,
269 : "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
270 : " copyOnWrite();\n"
271 : " instance.set$capitalized_name$(value);\n"
272 : " return this;\n"
273 0 : "}\n");
274 :
275 0 : WriteFieldDocComment(printer, descriptor_);
276 : printer->Print(variables_,
277 : "$deprecation$public Builder clear$capitalized_name$() {\n"
278 : " copyOnWrite();\n"
279 : " instance.clear$capitalized_name$();\n"
280 : " return this;\n"
281 0 : "}\n");
282 0 : }
283 :
284 0 : void ImmutablePrimitiveFieldLiteGenerator::
285 : GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
286 : // noop for primitives
287 0 : }
288 :
289 0 : void ImmutablePrimitiveFieldLiteGenerator::
290 : GenerateInitializationCode(io::Printer* printer) const {
291 0 : printer->Print(variables_, "$name$_ = $default$;\n");
292 0 : }
293 :
294 0 : void ImmutablePrimitiveFieldLiteGenerator::
295 : GenerateBuilderClearCode(io::Printer* printer) const {
296 : // noop for primitives
297 0 : }
298 :
299 0 : void ImmutablePrimitiveFieldLiteGenerator::
300 : GenerateMergingCode(io::Printer* printer) const {
301 0 : if (SupportFieldPresence(descriptor_->file())) {
302 : printer->Print(variables_,
303 : "if (other.has$capitalized_name$()) {\n"
304 : " set$capitalized_name$(other.get$capitalized_name$());\n"
305 0 : "}\n");
306 : } else {
307 : printer->Print(variables_,
308 : "if (other.get$capitalized_name$() != $default$) {\n"
309 : " set$capitalized_name$(other.get$capitalized_name$());\n"
310 0 : "}\n");
311 : }
312 0 : }
313 :
314 0 : void ImmutablePrimitiveFieldLiteGenerator::
315 : GenerateBuildingCode(io::Printer* printer) const {
316 : // noop for primitives
317 0 : }
318 :
319 0 : void ImmutablePrimitiveFieldLiteGenerator::
320 : GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
321 : // noop for scalars
322 0 : }
323 :
324 0 : void ImmutablePrimitiveFieldLiteGenerator::
325 : GenerateParsingCode(io::Printer* printer) const {
326 : printer->Print(variables_,
327 : "$set_has_field_bit_message$\n"
328 0 : "$name$_ = input.read$capitalized_type$();\n");
329 0 : }
330 :
331 0 : void ImmutablePrimitiveFieldLiteGenerator::
332 : GenerateParsingDoneCode(io::Printer* printer) const {
333 : // noop for primitives.
334 0 : }
335 :
336 0 : void ImmutablePrimitiveFieldLiteGenerator::
337 : GenerateSerializationCode(io::Printer* printer) const {
338 : printer->Print(variables_,
339 : "if ($is_field_present_message$) {\n"
340 : " output.write$capitalized_type$($number$, $name$_);\n"
341 0 : "}\n");
342 0 : }
343 :
344 0 : void ImmutablePrimitiveFieldLiteGenerator::
345 : GenerateSerializedSizeCode(io::Printer* printer) const {
346 : printer->Print(variables_,
347 : "if ($is_field_present_message$) {\n"
348 : " size += com.google.protobuf.CodedOutputStream\n"
349 : " .compute$capitalized_type$Size($number$, $name$_);\n"
350 0 : "}\n");
351 0 : }
352 :
353 0 : void ImmutablePrimitiveFieldLiteGenerator::
354 : GenerateEqualsCode(io::Printer* printer) const {
355 0 : switch (GetJavaType(descriptor_)) {
356 : case JAVATYPE_INT:
357 : case JAVATYPE_LONG:
358 : case JAVATYPE_BOOLEAN:
359 : printer->Print(variables_,
360 : "result = result && (get$capitalized_name$()\n"
361 0 : " == other.get$capitalized_name$());\n");
362 0 : break;
363 :
364 : case JAVATYPE_FLOAT:
365 : printer->Print(variables_,
366 : "result = result && (\n"
367 : " java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
368 : " == java.lang.Float.floatToIntBits(\n"
369 0 : " other.get$capitalized_name$()));\n");
370 0 : break;
371 :
372 : case JAVATYPE_DOUBLE:
373 : printer->Print(variables_,
374 : "result = result && (\n"
375 : " java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
376 : " == java.lang.Double.doubleToLongBits(\n"
377 0 : " other.get$capitalized_name$()));\n");
378 0 : break;
379 :
380 : case JAVATYPE_STRING:
381 : case JAVATYPE_BYTES:
382 : printer->Print(variables_,
383 : "result = result && get$capitalized_name$()\n"
384 0 : " .equals(other.get$capitalized_name$());\n");
385 0 : break;
386 :
387 : case JAVATYPE_ENUM:
388 : case JAVATYPE_MESSAGE:
389 : default:
390 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
391 0 : break;
392 : }
393 0 : }
394 :
395 0 : void ImmutablePrimitiveFieldLiteGenerator::
396 : GenerateHashCode(io::Printer* printer) const {
397 : printer->Print(variables_,
398 0 : "hash = (37 * hash) + $constant_name$;\n");
399 0 : switch (GetJavaType(descriptor_)) {
400 : case JAVATYPE_INT:
401 : printer->Print(variables_,
402 0 : "hash = (53 * hash) + get$capitalized_name$();\n");
403 0 : break;
404 :
405 : case JAVATYPE_LONG:
406 : printer->Print(variables_,
407 : "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
408 0 : " get$capitalized_name$());\n");
409 0 : break;
410 :
411 : case JAVATYPE_BOOLEAN:
412 : printer->Print(variables_,
413 : "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"
414 0 : " get$capitalized_name$());\n");
415 0 : break;
416 :
417 : case JAVATYPE_FLOAT:
418 : printer->Print(variables_,
419 : "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"
420 0 : " get$capitalized_name$());\n");
421 0 : break;
422 :
423 : case JAVATYPE_DOUBLE:
424 : printer->Print(variables_,
425 : "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
426 0 : " java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n");
427 0 : break;
428 :
429 : case JAVATYPE_STRING:
430 : case JAVATYPE_BYTES:
431 : printer->Print(variables_,
432 0 : "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
433 0 : break;
434 :
435 : case JAVATYPE_ENUM:
436 : case JAVATYPE_MESSAGE:
437 : default:
438 0 : GOOGLE_LOG(FATAL) << "Can't get here.";
439 0 : break;
440 : }
441 0 : }
442 :
443 0 : string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
444 0 : return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
445 : }
446 :
447 : // ===================================================================
448 :
449 0 : ImmutablePrimitiveOneofFieldLiteGenerator::
450 0 : ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
451 : int messageBitIndex,
452 : int builderBitIndex,
453 : Context* context)
454 : : ImmutablePrimitiveFieldLiteGenerator(
455 0 : descriptor, messageBitIndex, builderBitIndex, context) {
456 : const OneofGeneratorInfo* info =
457 0 : context->GetOneofGeneratorInfo(descriptor->containing_oneof());
458 0 : SetCommonOneofVariables(descriptor, info, &variables_);
459 0 : }
460 :
461 0 : ImmutablePrimitiveOneofFieldLiteGenerator::
462 0 : ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
463 :
464 0 : void ImmutablePrimitiveOneofFieldLiteGenerator::
465 : GenerateMembers(io::Printer* printer) const {
466 0 : PrintExtraFieldInfo(variables_, printer);
467 0 : if (SupportFieldPresence(descriptor_->file())) {
468 0 : WriteFieldDocComment(printer, descriptor_);
469 : printer->Print(variables_,
470 : "$deprecation$public boolean has$capitalized_name$() {\n"
471 : " return $has_oneof_case_message$;\n"
472 0 : "}\n");
473 : }
474 :
475 0 : 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 0 : "}\n");
483 :
484 0 : WriteFieldDocComment(printer, descriptor_);
485 : printer->Print(variables_,
486 : "private void set$capitalized_name$($type$ value) {\n"
487 : "$null_check$"
488 : " $set_oneof_case_message$;\n"
489 : " $oneof_name$_ = value;\n"
490 0 : "}\n");
491 :
492 0 : WriteFieldDocComment(printer, descriptor_);
493 : printer->Print(variables_,
494 : "private void clear$capitalized_name$() {\n"
495 : " if ($has_oneof_case_message$) {\n"
496 : " $clear_oneof_case_message$;\n"
497 : " $oneof_name$_ = null;\n"
498 : " }\n"
499 0 : "}\n");
500 0 : }
501 :
502 :
503 0 : void ImmutablePrimitiveOneofFieldLiteGenerator::
504 : GenerateBuilderMembers(io::Printer* printer) const {
505 0 : if (SupportFieldPresence(descriptor_->file())) {
506 0 : WriteFieldDocComment(printer, descriptor_);
507 : printer->Print(variables_,
508 : "$deprecation$public boolean has$capitalized_name$() {\n"
509 : " return instance.has$capitalized_name$();\n"
510 0 : "}\n");
511 : }
512 :
513 0 : WriteFieldDocComment(printer, descriptor_);
514 : printer->Print(variables_,
515 : "$deprecation$public $type$ get$capitalized_name$() {\n"
516 : " return instance.get$capitalized_name$();\n"
517 0 : "}\n");
518 :
519 0 : WriteFieldDocComment(printer, descriptor_);
520 : printer->Print(variables_,
521 : "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
522 : " copyOnWrite();\n"
523 : " instance.set$capitalized_name$(value);\n"
524 : " return this;\n"
525 0 : "}\n");
526 :
527 0 : WriteFieldDocComment(printer, descriptor_);
528 : printer->Print(variables_,
529 : "$deprecation$public Builder clear$capitalized_name$() {\n"
530 : " copyOnWrite();\n"
531 : " instance.clear$capitalized_name$();\n"
532 : " return this;\n"
533 0 : "}\n");
534 0 : }
535 :
536 0 : void ImmutablePrimitiveOneofFieldLiteGenerator::
537 : GenerateBuildingCode(io::Printer* printer) const {
538 : // noop for primitives
539 0 : }
540 :
541 0 : void ImmutablePrimitiveOneofFieldLiteGenerator::
542 : GenerateMergingCode(io::Printer* printer) const {
543 : printer->Print(variables_,
544 0 : "set$capitalized_name$(other.get$capitalized_name$());\n");
545 0 : }
546 :
547 0 : void ImmutablePrimitiveOneofFieldLiteGenerator::
548 : GenerateParsingCode(io::Printer* printer) const {
549 : printer->Print(variables_,
550 : "$set_oneof_case_message$;\n"
551 0 : "$oneof_name$_ = input.read$capitalized_type$();\n");
552 0 : }
553 :
554 0 : void ImmutablePrimitiveOneofFieldLiteGenerator::
555 : GenerateSerializationCode(io::Printer* printer) const {
556 : printer->Print(variables_,
557 : "if ($has_oneof_case_message$) {\n"
558 : " output.write$capitalized_type$(\n"
559 : " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
560 0 : "}\n");
561 0 : }
562 :
563 0 : void ImmutablePrimitiveOneofFieldLiteGenerator::
564 : GenerateSerializedSizeCode(io::Printer* printer) const {
565 : printer->Print(variables_,
566 : "if ($has_oneof_case_message$) {\n"
567 : " size += com.google.protobuf.CodedOutputStream\n"
568 : " .compute$capitalized_type$Size(\n"
569 : " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
570 0 : "}\n");
571 0 : }
572 :
573 : // ===================================================================
574 :
575 0 : RepeatedImmutablePrimitiveFieldLiteGenerator::
576 : RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor* descriptor,
577 : int messageBitIndex,
578 : int builderBitIndex,
579 : Context* context)
580 : : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
581 : builderBitIndex_(builderBitIndex), context_(context),
582 0 : name_resolver_(context->GetNameResolver()) {
583 : SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
584 : context->GetFieldGeneratorInfo(descriptor),
585 0 : name_resolver_, &variables_);
586 0 : }
587 :
588 0 : RepeatedImmutablePrimitiveFieldLiteGenerator::
589 0 : ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
590 :
591 0 : int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
592 0 : return 0;
593 : }
594 :
595 0 : int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForBuilder() const {
596 0 : return 0;
597 : }
598 :
599 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
600 : GenerateInterfaceMembers(io::Printer* printer) const {
601 0 : WriteFieldDocComment(printer, descriptor_);
602 : printer->Print(variables_,
603 0 : "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n");
604 0 : WriteFieldDocComment(printer, descriptor_);
605 : printer->Print(variables_,
606 0 : "$deprecation$int get$capitalized_name$Count();\n");
607 0 : WriteFieldDocComment(printer, descriptor_);
608 : printer->Print(variables_,
609 0 : "$deprecation$$type$ get$capitalized_name$(int index);\n");
610 0 : }
611 :
612 :
613 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
614 : GenerateMembers(io::Printer* printer) const {
615 : printer->Print(variables_,
616 0 : "private $field_list_type$ $name$_;\n");
617 0 : PrintExtraFieldInfo(variables_, printer);
618 0 : WriteFieldDocComment(printer, descriptor_);
619 : printer->Print(variables_,
620 : "$deprecation$public java.util.List<$boxed_type$>\n"
621 : " get$capitalized_name$List() {\n"
622 : " return $name$_;\n" // note: unmodifiable list
623 0 : "}\n");
624 0 : WriteFieldDocComment(printer, descriptor_);
625 : printer->Print(variables_,
626 : "$deprecation$public int get$capitalized_name$Count() {\n"
627 : " return $name$_.size();\n"
628 0 : "}\n");
629 0 : WriteFieldDocComment(printer, descriptor_);
630 : printer->Print(variables_,
631 : "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
632 : " return $repeated_index_get$;\n"
633 0 : "}\n");
634 :
635 0 : if (descriptor_->options().packed() &&
636 0 : HasGeneratedMethods(descriptor_->containing_type())) {
637 : printer->Print(variables_,
638 0 : "private int $name$MemoizedSerializedSize = -1;\n");
639 : }
640 :
641 : printer->Print(variables_,
642 : "private void ensure$capitalized_name$IsMutable() {\n"
643 : " if (!$is_mutable$) {\n"
644 : " $name$_ = $new_list$($name$_);\n"
645 : " }\n"
646 0 : "}\n");
647 :
648 0 : WriteFieldDocComment(printer, descriptor_);
649 : printer->Print(variables_,
650 : "private void set$capitalized_name$(\n"
651 : " int index, $type$ value) {\n"
652 : "$null_check$"
653 : " ensure$capitalized_name$IsMutable();\n"
654 : " $repeated_set$(index, value);\n"
655 0 : "}\n");
656 0 : WriteFieldDocComment(printer, descriptor_);
657 : printer->Print(variables_,
658 : "private void add$capitalized_name$($type$ value) {\n"
659 : "$null_check$"
660 : " ensure$capitalized_name$IsMutable();\n"
661 : " $repeated_add$(value);\n"
662 0 : "}\n");
663 0 : WriteFieldDocComment(printer, descriptor_);
664 : printer->Print(variables_,
665 : "private void addAll$capitalized_name$(\n"
666 : " java.lang.Iterable<? extends $boxed_type$> values) {\n"
667 : " ensure$capitalized_name$IsMutable();\n"
668 : " com.google.protobuf.AbstractMessageLite.addAll(\n"
669 : " values, $name$_);\n"
670 0 : "}\n");
671 0 : WriteFieldDocComment(printer, descriptor_);
672 : printer->Print(variables_,
673 : "private void clear$capitalized_name$() {\n"
674 : " $name$_ = $empty_list$;\n"
675 0 : "}\n");
676 0 : }
677 :
678 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
679 : GenerateBuilderMembers(io::Printer* printer) const {
680 0 : WriteFieldDocComment(printer, descriptor_);
681 : printer->Print(variables_,
682 : "$deprecation$public java.util.List<$boxed_type$>\n"
683 : " get$capitalized_name$List() {\n"
684 : " return java.util.Collections.unmodifiableList(\n"
685 : " instance.get$capitalized_name$List());\n"
686 0 : "}\n");
687 0 : WriteFieldDocComment(printer, descriptor_);
688 : printer->Print(variables_,
689 : "$deprecation$public int get$capitalized_name$Count() {\n"
690 : " return instance.get$capitalized_name$Count();\n"
691 0 : "}\n");
692 0 : WriteFieldDocComment(printer, descriptor_);
693 : printer->Print(variables_,
694 : "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
695 : " return instance.get$capitalized_name$(index);\n"
696 0 : "}\n");
697 0 : WriteFieldDocComment(printer, descriptor_);
698 : printer->Print(variables_,
699 : "$deprecation$public Builder set$capitalized_name$(\n"
700 : " int index, $type$ value) {\n"
701 : " copyOnWrite();\n"
702 : " instance.set$capitalized_name$(index, value);\n"
703 : " return this;\n"
704 0 : "}\n");
705 0 : WriteFieldDocComment(printer, descriptor_);
706 : printer->Print(variables_,
707 : "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
708 : " copyOnWrite();\n"
709 : " instance.add$capitalized_name$(value);\n"
710 : " return this;\n"
711 0 : "}\n");
712 0 : WriteFieldDocComment(printer, descriptor_);
713 : printer->Print(variables_,
714 : "$deprecation$public Builder addAll$capitalized_name$(\n"
715 : " java.lang.Iterable<? extends $boxed_type$> values) {\n"
716 : " copyOnWrite();\n"
717 : " instance.addAll$capitalized_name$(values);\n"
718 : " return this;\n"
719 0 : "}\n");
720 0 : WriteFieldDocComment(printer, descriptor_);
721 : printer->Print(variables_,
722 : "$deprecation$public Builder clear$capitalized_name$() {\n"
723 : " copyOnWrite();\n"
724 : " instance.clear$capitalized_name$();\n"
725 : " return this;\n"
726 0 : "}\n");
727 0 : }
728 :
729 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
730 : GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
731 : // noop for primitives
732 0 : }
733 :
734 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
735 : GenerateInitializationCode(io::Printer* printer) const {
736 0 : printer->Print(variables_, "$name$_ = $empty_list$;\n");
737 0 : }
738 :
739 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
740 : GenerateBuilderClearCode(io::Printer* printer) const {
741 : // noop for primitives
742 0 : }
743 :
744 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
745 : GenerateMergingCode(io::Printer* printer) const {
746 : // The code below does two optimizations:
747 : // 1. If the other list is empty, there's nothing to do. This ensures we
748 : // don't allocate a new array if we already have an immutable one.
749 : // 2. If the other list is non-empty and our current list is empty, we can
750 : // reuse the other list which is guaranteed to be immutable.
751 : printer->Print(variables_,
752 : "if (!other.$name$_.isEmpty()) {\n"
753 : " if ($name$_.isEmpty()) {\n"
754 : " $name$_ = other.$name$_;\n"
755 : " } else {\n"
756 : " ensure$capitalized_name$IsMutable();\n"
757 : " $name$_.addAll(other.$name$_);\n"
758 : " }\n"
759 : " $on_changed$\n"
760 0 : "}\n");
761 0 : }
762 :
763 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
764 : GenerateBuildingCode(io::Printer* printer) const {
765 : // noop for primitives
766 0 : }
767 :
768 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
769 : GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
770 : printer->Print(variables_,
771 0 : "$name$_.makeImmutable();\n");
772 0 : }
773 :
774 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
775 : GenerateParsingCode(io::Printer* printer) const {
776 : printer->Print(variables_,
777 : "if (!$is_mutable$) {\n"
778 : " $name$_ = $new_list$();\n"
779 : "}\n"
780 0 : "$repeated_add$(input.read$capitalized_type$());\n");
781 0 : }
782 :
783 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
784 : GenerateParsingCodeFromPacked(io::Printer* printer) const {
785 : printer->Print(variables_,
786 : "int length = input.readRawVarint32();\n"
787 : "int limit = input.pushLimit(length);\n"
788 : "if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n"
789 : " $name$_ = $new_list$();\n"
790 : "}\n"
791 : "while (input.getBytesUntilLimit() > 0) {\n"
792 : " $repeated_add$(input.read$capitalized_type$());\n"
793 : "}\n"
794 0 : "input.popLimit(limit);\n");
795 0 : }
796 :
797 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
798 : GenerateParsingDoneCode(io::Printer* printer) const {
799 : printer->Print(variables_,
800 : "if ($is_mutable$) {\n"
801 : " $make_name_unmodifiable$;\n"
802 0 : "}\n");
803 0 : }
804 :
805 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
806 : GenerateSerializationCode(io::Printer* printer) const {
807 0 : if (descriptor_->options().packed()) {
808 : // We invoke getSerializedSize in writeTo for messages that have packed
809 : // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods.
810 : // That makes it safe to rely on the memoized size here.
811 : printer->Print(variables_,
812 : "if (get$capitalized_name$List().size() > 0) {\n"
813 : " output.writeRawVarint32($tag$);\n"
814 : " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
815 : "}\n"
816 : "for (int i = 0; i < $name$_.size(); i++) {\n"
817 : " output.write$capitalized_type$NoTag($name$_.get(i));\n"
818 0 : "}\n");
819 : } else {
820 : printer->Print(variables_,
821 : "for (int i = 0; i < $name$_.size(); i++) {\n"
822 : " output.write$capitalized_type$($number$, $name$_.get(i));\n"
823 0 : "}\n");
824 : }
825 0 : }
826 :
827 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
828 : GenerateSerializedSizeCode(io::Printer* printer) const {
829 : printer->Print(variables_,
830 : "{\n"
831 0 : " int dataSize = 0;\n");
832 0 : printer->Indent();
833 :
834 0 : if (FixedSize(GetType(descriptor_)) == -1) {
835 : printer->Print(variables_,
836 : "for (int i = 0; i < $name$_.size(); i++) {\n"
837 : " dataSize += com.google.protobuf.CodedOutputStream\n"
838 : " .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
839 0 : "}\n");
840 : } else {
841 : printer->Print(variables_,
842 0 : "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
843 : }
844 :
845 : printer->Print(
846 0 : "size += dataSize;\n");
847 :
848 0 : if (descriptor_->options().packed()) {
849 : printer->Print(variables_,
850 : "if (!get$capitalized_name$List().isEmpty()) {\n"
851 : " size += $tag_size$;\n"
852 : " size += com.google.protobuf.CodedOutputStream\n"
853 : " .computeInt32SizeNoTag(dataSize);\n"
854 0 : "}\n");
855 : } else {
856 : printer->Print(variables_,
857 0 : "size += $tag_size$ * get$capitalized_name$List().size();\n");
858 : }
859 :
860 : // cache the data size for packed fields.
861 0 : if (descriptor_->options().packed()) {
862 : printer->Print(variables_,
863 0 : "$name$MemoizedSerializedSize = dataSize;\n");
864 : }
865 :
866 0 : printer->Outdent();
867 0 : printer->Print("}\n");
868 0 : }
869 :
870 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
871 : GenerateEqualsCode(io::Printer* printer) const {
872 : printer->Print(variables_,
873 : "result = result && get$capitalized_name$List()\n"
874 0 : " .equals(other.get$capitalized_name$List());\n");
875 0 : }
876 :
877 0 : void RepeatedImmutablePrimitiveFieldLiteGenerator::
878 : GenerateHashCode(io::Printer* printer) const {
879 : printer->Print(variables_,
880 : "if (get$capitalized_name$Count() > 0) {\n"
881 : " hash = (37 * hash) + $constant_name$;\n"
882 : " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
883 0 : "}\n");
884 0 : }
885 :
886 0 : string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
887 0 : return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
888 : }
889 :
890 : } // namespace java
891 : } // namespace compiler
892 : } // namespace protobuf
893 : } // namespace google
|