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
50 namespace google {
51 namespace protobuf {
52 namespace compiler {
53 namespace java {
54
55 using internal::WireFormat;
56 using internal::WireFormatLite;
57
58 namespace {
EnableExperimentalRuntimeForLite()59 bool EnableExperimentalRuntimeForLite() {
60 #ifdef PROTOBUF_EXPERIMENT
61 return PROTOBUF_EXPERIMENT;
62 #else // PROTOBUF_EXPERIMENT
63 return false;
64 #endif // !PROTOBUF_EXPERIMENT
65 }
66
SetPrimitiveVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)67 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
68 int messageBitIndex, int builderBitIndex,
69 const FieldGeneratorInfo* info,
70 ClassNameResolver* name_resolver,
71 std::map<std::string, std::string>* variables) {
72 SetCommonFieldVariables(descriptor, info, variables);
73 JavaType javaType = GetJavaType(descriptor);
74 (*variables)["type"] = PrimitiveTypeName(javaType);
75 (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
76 (*variables)["field_type"] = (*variables)["type"];
77 (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
78 (*variables)["capitalized_type"] =
79 GetCapitalizedType(descriptor, /* immutable = */ true);
80 (*variables)["tag"] =
81 StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
82 (*variables)["tag_size"] = StrCat(
83 WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
84 (*variables)["required"] = descriptor->is_required() ? "true" : "false";
85
86 std::string capitalized_type = UnderscoresToCamelCase(
87 PrimitiveTypeName(javaType), true /* cap_next_letter */);
88 switch (javaType) {
89 case JAVATYPE_INT:
90 case JAVATYPE_LONG:
91 case JAVATYPE_FLOAT:
92 case JAVATYPE_DOUBLE:
93 case JAVATYPE_BOOLEAN:
94 (*variables)["field_list_type"] =
95 "com.google.protobuf.Internal." + capitalized_type + "List";
96 (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
97 (*variables)["make_name_unmodifiable"] =
98 (*variables)["name"] + "_.makeImmutable()";
99 (*variables)["repeated_get"] =
100 (*variables)["name"] + "_.get" + capitalized_type;
101 (*variables)["repeated_add"] =
102 (*variables)["name"] + "_.add" + capitalized_type;
103 (*variables)["repeated_set"] =
104 (*variables)["name"] + "_.set" + capitalized_type;
105 (*variables)["visit_type"] = capitalized_type;
106 (*variables)["visit_type_list"] = "visit" + capitalized_type + "List";
107 break;
108 default:
109 (*variables)["field_list_type"] =
110 "com.google.protobuf.Internal.ProtobufList<" +
111 (*variables)["boxed_type"] + ">";
112 (*variables)["empty_list"] = "emptyProtobufList()";
113 (*variables)["make_name_unmodifiable"] =
114 (*variables)["name"] + "_.makeImmutable()";
115 (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
116 (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
117 (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
118 (*variables)["visit_type"] = "ByteString";
119 (*variables)["visit_type_list"] = "visitList";
120 }
121
122 if (javaType == JAVATYPE_BYTES) {
123 (*variables)["bytes_default"] =
124 ToUpper((*variables)["name"]) + "_DEFAULT_VALUE";
125 }
126
127 if (IsReferenceType(javaType)) {
128 (*variables)["null_check"] =
129 " if (value == null) {\n"
130 " throw new NullPointerException();\n"
131 " }\n";
132 } else {
133 (*variables)["null_check"] = "";
134 }
135 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
136 // by the proto compiler
137 (*variables)["deprecation"] =
138 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
139 int fixed_size = FixedSize(GetType(descriptor));
140 if (fixed_size != -1) {
141 (*variables)["fixed_size"] = StrCat(fixed_size);
142 }
143
144 if (SupportFieldPresence(descriptor->file())) {
145 // For singular messages and builders, one bit is used for the hasField bit.
146 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
147
148 // Note that these have a trailing ";".
149 (*variables)["set_has_field_bit_message"] =
150 GenerateSetBit(messageBitIndex) + ";";
151 (*variables)["clear_has_field_bit_message"] =
152 GenerateClearBit(messageBitIndex) + ";";
153
154 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
155 } else {
156 (*variables)["set_has_field_bit_message"] = "";
157 (*variables)["set_has_field_bit_message"] = "";
158 (*variables)["clear_has_field_bit_message"] = "";
159
160 if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
161 (*variables)["is_field_present_message"] =
162 "!" + (*variables)["name"] + "_.isEmpty()";
163 } else {
164 (*variables)["is_field_present_message"] =
165 (*variables)["name"] + "_ != " + (*variables)["default"];
166 }
167 }
168
169 // For repeated builders, the underlying list tracks mutability state.
170 (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
171
172 (*variables)["get_has_field_bit_from_local"] =
173 GenerateGetBitFromLocal(builderBitIndex);
174 (*variables)["set_has_field_bit_to_local"] =
175 GenerateSetBitToLocal(messageBitIndex);
176 }
177
178 } // namespace
179
180 // ===================================================================
181
ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)182 ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
183 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
184 : descriptor_(descriptor),
185 messageBitIndex_(messageBitIndex),
186 name_resolver_(context->GetNameResolver()) {
187 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
188 context->GetFieldGeneratorInfo(descriptor),
189 name_resolver_, &variables_);
190 }
191
~ImmutablePrimitiveFieldLiteGenerator()192 ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
193
GetNumBitsForMessage() const194 int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
195 return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
196 }
197
GenerateInterfaceMembers(io::Printer * printer) const198 void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
199 io::Printer* printer) const {
200 if (SupportFieldPresence(descriptor_->file())) {
201 WriteFieldDocComment(printer, descriptor_);
202 printer->Print(variables_,
203 "$deprecation$boolean has$capitalized_name$();\n");
204 }
205 WriteFieldDocComment(printer, descriptor_);
206 printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
207 }
208
GenerateMembers(io::Printer * printer) const209 void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
210 io::Printer* printer) const {
211 if (IsByteStringWithCustomDefaultValue(descriptor_)) {
212 // allocate this once statically since we know ByteStrings are immutable
213 // values that can be reused.
214 printer->Print(
215 variables_,
216 "private static final $field_type$ $bytes_default$ = $default$;\n");
217 }
218 printer->Print(variables_, "private $field_type$ $name$_;\n");
219 PrintExtraFieldInfo(variables_, printer);
220 if (SupportFieldPresence(descriptor_->file())) {
221 WriteFieldDocComment(printer, descriptor_);
222 printer->Print(
223 variables_,
224 "@java.lang.Override\n"
225 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
226 " return $get_has_field_bit_message$;\n"
227 "}\n");
228 printer->Annotate("{", "}", descriptor_);
229 }
230
231 WriteFieldDocComment(printer, descriptor_);
232 printer->Print(variables_,
233 "@java.lang.Override\n"
234 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
235 " return $name$_;\n"
236 "}\n");
237 printer->Annotate("{", "}", descriptor_);
238
239 WriteFieldDocComment(printer, descriptor_);
240 printer->Print(variables_,
241 "private void set$capitalized_name$($type$ value) {\n"
242 "$null_check$"
243 " $set_has_field_bit_message$\n"
244 " $name$_ = value;\n"
245 "}\n");
246
247 WriteFieldDocComment(printer, descriptor_);
248 printer->Print(variables_,
249 "private void clear$capitalized_name$() {\n"
250 " $clear_has_field_bit_message$\n");
251 JavaType type = GetJavaType(descriptor_);
252 if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
253 // The default value is not a simple literal so we want to avoid executing
254 // it multiple times. Instead, get the default out of the default instance.
255 printer->Print(
256 variables_,
257 " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
258 } else {
259 printer->Print(variables_, " $name$_ = $default$;\n");
260 }
261 printer->Print(variables_, "}\n");
262 }
263
GenerateBuilderMembers(io::Printer * printer) const264 void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
265 io::Printer* printer) const {
266 if (SupportFieldPresence(descriptor_->file())) {
267 WriteFieldDocComment(printer, descriptor_);
268 printer->Print(
269 variables_,
270 "@java.lang.Override\n"
271 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
272 " return instance.has$capitalized_name$();\n"
273 "}\n");
274 printer->Annotate("{", "}", descriptor_);
275 }
276
277 WriteFieldDocComment(printer, descriptor_);
278 printer->Print(variables_,
279 "@java.lang.Override\n"
280 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
281 " return instance.get$capitalized_name$();\n"
282 "}\n");
283 printer->Annotate("{", "}", descriptor_);
284
285 WriteFieldDocComment(printer, descriptor_);
286 printer->Print(variables_,
287 "$deprecation$public Builder "
288 "${$set$capitalized_name$$}$($type$ value) {\n"
289 " copyOnWrite();\n"
290 " instance.set$capitalized_name$(value);\n"
291 " return this;\n"
292 "}\n");
293 printer->Annotate("{", "}", descriptor_);
294
295 WriteFieldDocComment(printer, descriptor_);
296 printer->Print(
297 variables_,
298 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
299 " copyOnWrite();\n"
300 " instance.clear$capitalized_name$();\n"
301 " return this;\n"
302 "}\n");
303 printer->Annotate("{", "}", descriptor_);
304 }
305
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const306 void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
307 io::Printer* printer, std::vector<uint16>* output) const {
308 WriteIntToUtf16CharSequence(descriptor_->number(), output);
309 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
310 output);
311 if (SupportFieldPresence(descriptor_->file())) {
312 WriteIntToUtf16CharSequence(messageBitIndex_, output);
313 }
314 printer->Print(variables_, "\"$name$_\",\n");
315 }
316
GenerateInitializationCode(io::Printer * printer) const317 void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
318 io::Printer* printer) const {
319 if (IsByteStringWithCustomDefaultValue(descriptor_)) {
320 printer->Print(variables_, "$name$_ = $bytes_default$;\n");
321 } else if (!IsDefaultValueJavaDefault(descriptor_)) {
322 printer->Print(variables_, "$name$_ = $default$;\n");
323 }
324 }
325
GetBoxedType() const326 std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
327 return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
328 }
329
330 // ===================================================================
331
332 ImmutablePrimitiveOneofFieldLiteGenerator::
ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)333 ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
334 int messageBitIndex,
335 Context* context)
336 : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
337 context) {
338 const OneofGeneratorInfo* info =
339 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
340 SetCommonOneofVariables(descriptor, info, &variables_);
341 }
342
343 ImmutablePrimitiveOneofFieldLiteGenerator::
~ImmutablePrimitiveOneofFieldLiteGenerator()344 ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
345
GenerateMembers(io::Printer * printer) const346 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers(
347 io::Printer* printer) const {
348 PrintExtraFieldInfo(variables_, printer);
349 if (SupportFieldPresence(descriptor_->file())) {
350 WriteFieldDocComment(printer, descriptor_);
351 printer->Print(
352 variables_,
353 "@java.lang.Override\n"
354 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
355 " return $has_oneof_case_message$;\n"
356 "}\n");
357 printer->Annotate("{", "}", descriptor_);
358 }
359
360 WriteFieldDocComment(printer, descriptor_);
361 printer->Print(variables_,
362 "@java.lang.Override\n"
363 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
364 " if ($has_oneof_case_message$) {\n"
365 " return ($boxed_type$) $oneof_name$_;\n"
366 " }\n"
367 " return $default$;\n"
368 "}\n");
369 printer->Annotate("{", "}", descriptor_);
370
371 WriteFieldDocComment(printer, descriptor_);
372 printer->Print(variables_,
373 "private void set$capitalized_name$($type$ value) {\n"
374 "$null_check$"
375 " $set_oneof_case_message$;\n"
376 " $oneof_name$_ = value;\n"
377 "}\n");
378
379 WriteFieldDocComment(printer, descriptor_);
380 printer->Print(variables_,
381 "private void clear$capitalized_name$() {\n"
382 " if ($has_oneof_case_message$) {\n"
383 " $clear_oneof_case_message$;\n"
384 " $oneof_name$_ = null;\n"
385 " }\n"
386 "}\n");
387 }
388
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const389 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo(
390 io::Printer* printer, std::vector<uint16>* output) const {
391 WriteIntToUtf16CharSequence(descriptor_->number(), output);
392 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
393 output);
394 WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
395 }
396
GenerateBuilderMembers(io::Printer * printer) const397 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers(
398 io::Printer* printer) const {
399 if (SupportFieldPresence(descriptor_->file())) {
400 WriteFieldDocComment(printer, descriptor_);
401 printer->Print(
402 variables_,
403 "@java.lang.Override\n"
404 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
405 " return instance.has$capitalized_name$();\n"
406 "}\n");
407 printer->Annotate("{", "}", descriptor_);
408 }
409
410 WriteFieldDocComment(printer, descriptor_);
411 printer->Print(variables_,
412 "@java.lang.Override\n"
413 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
414 " return instance.get$capitalized_name$();\n"
415 "}\n");
416 printer->Annotate("{", "}", descriptor_);
417
418 WriteFieldDocComment(printer, descriptor_);
419 printer->Print(variables_,
420 "$deprecation$public Builder "
421 "${$set$capitalized_name$$}$($type$ value) {\n"
422 " copyOnWrite();\n"
423 " instance.set$capitalized_name$(value);\n"
424 " return this;\n"
425 "}\n");
426 printer->Annotate("{", "}", descriptor_);
427
428 WriteFieldDocComment(printer, descriptor_);
429 printer->Print(
430 variables_,
431 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
432 " copyOnWrite();\n"
433 " instance.clear$capitalized_name$();\n"
434 " return this;\n"
435 "}\n");
436 printer->Annotate("{", "}", descriptor_);
437 }
438
439 // ===================================================================
440
441 RepeatedImmutablePrimitiveFieldLiteGenerator::
RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)442 RepeatedImmutablePrimitiveFieldLiteGenerator(
443 const FieldDescriptor* descriptor, int messageBitIndex,
444 Context* context)
445 : descriptor_(descriptor),
446 context_(context),
447 name_resolver_(context->GetNameResolver()) {
448 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
449 context->GetFieldGeneratorInfo(descriptor),
450 name_resolver_, &variables_);
451 }
452
453 RepeatedImmutablePrimitiveFieldLiteGenerator::
~RepeatedImmutablePrimitiveFieldLiteGenerator()454 ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
455
GetNumBitsForMessage() const456 int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
457 return 0;
458 }
459
GenerateInterfaceMembers(io::Printer * printer) const460 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
461 io::Printer* printer) const {
462 WriteFieldDocComment(printer, descriptor_);
463 printer->Print(variables_,
464 "$deprecation$java.util.List<$boxed_type$> "
465 "get$capitalized_name$List();\n");
466 WriteFieldDocComment(printer, descriptor_);
467 printer->Print(variables_,
468 "$deprecation$int get$capitalized_name$Count();\n");
469 WriteFieldDocComment(printer, descriptor_);
470 printer->Print(variables_,
471 "$deprecation$$type$ get$capitalized_name$(int index);\n");
472 }
473
GenerateMembers(io::Printer * printer) const474 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
475 io::Printer* printer) const {
476 printer->Print(variables_, "private $field_list_type$ $name$_;\n");
477 PrintExtraFieldInfo(variables_, printer);
478 WriteFieldDocComment(printer, descriptor_);
479 printer->Print(variables_,
480 "@java.lang.Override\n"
481 "$deprecation$public java.util.List<$boxed_type$>\n"
482 " ${$get$capitalized_name$List$}$() {\n"
483 " return $name$_;\n" // note: unmodifiable list
484 "}\n");
485 printer->Annotate("{", "}", descriptor_);
486 WriteFieldDocComment(printer, descriptor_);
487 printer->Print(
488 variables_,
489 "@java.lang.Override\n"
490 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
491 " return $name$_.size();\n"
492 "}\n");
493 printer->Annotate("{", "}", descriptor_);
494 WriteFieldDocComment(printer, descriptor_);
495 printer->Print(
496 variables_,
497 "@java.lang.Override\n"
498 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
499 " return $repeated_get$(index);\n"
500 "}\n");
501 printer->Annotate("{", "}", descriptor_);
502
503 if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
504 context_->HasGeneratedMethods(descriptor_->containing_type())) {
505 printer->Print(variables_,
506 "private int $name$MemoizedSerializedSize = -1;\n");
507 }
508
509 printer->Print(
510 variables_,
511 "private void ensure$capitalized_name$IsMutable() {\n"
512 " if (!$is_mutable$) {\n"
513 " $name$_ =\n"
514 " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
515 " }\n"
516 "}\n");
517
518 WriteFieldDocComment(printer, descriptor_);
519 printer->Print(variables_,
520 "private void set$capitalized_name$(\n"
521 " int index, $type$ value) {\n"
522 "$null_check$"
523 " ensure$capitalized_name$IsMutable();\n"
524 " $repeated_set$(index, value);\n"
525 "}\n");
526 WriteFieldDocComment(printer, descriptor_);
527 printer->Print(variables_,
528 "private void add$capitalized_name$($type$ value) {\n"
529 "$null_check$"
530 " ensure$capitalized_name$IsMutable();\n"
531 " $repeated_add$(value);\n"
532 "}\n");
533 WriteFieldDocComment(printer, descriptor_);
534 printer->Print(variables_,
535 "private void addAll$capitalized_name$(\n"
536 " java.lang.Iterable<? extends $boxed_type$> values) {\n"
537 " ensure$capitalized_name$IsMutable();\n"
538 " com.google.protobuf.AbstractMessageLite.addAll(\n"
539 " values, $name$_);\n"
540 "}\n");
541 WriteFieldDocComment(printer, descriptor_);
542 printer->Print(variables_,
543 "private void clear$capitalized_name$() {\n"
544 " $name$_ = $empty_list$;\n"
545 "}\n");
546 }
547
GenerateBuilderMembers(io::Printer * printer) const548 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
549 io::Printer* printer) const {
550 WriteFieldDocComment(printer, descriptor_);
551 printer->Print(variables_,
552 "@java.lang.Override\n"
553 "$deprecation$public java.util.List<$boxed_type$>\n"
554 " ${$get$capitalized_name$List$}$() {\n"
555 " return java.util.Collections.unmodifiableList(\n"
556 " instance.get$capitalized_name$List());\n"
557 "}\n");
558 printer->Annotate("{", "}", descriptor_);
559 WriteFieldDocComment(printer, descriptor_);
560 printer->Print(
561 variables_,
562 "@java.lang.Override\n"
563 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
564 " return instance.get$capitalized_name$Count();\n"
565 "}\n");
566 printer->Annotate("{", "}", descriptor_);
567 WriteFieldDocComment(printer, descriptor_);
568 printer->Print(
569 variables_,
570 "@java.lang.Override\n"
571 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
572 " return instance.get$capitalized_name$(index);\n"
573 "}\n");
574 printer->Annotate("{", "}", descriptor_);
575 WriteFieldDocComment(printer, descriptor_);
576 printer->Print(variables_,
577 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
578 " int index, $type$ value) {\n"
579 " copyOnWrite();\n"
580 " instance.set$capitalized_name$(index, value);\n"
581 " return this;\n"
582 "}\n");
583 printer->Annotate("{", "}", descriptor_);
584 WriteFieldDocComment(printer, descriptor_);
585 printer->Print(variables_,
586 "$deprecation$public Builder "
587 "${$add$capitalized_name$$}$($type$ value) {\n"
588 " copyOnWrite();\n"
589 " instance.add$capitalized_name$(value);\n"
590 " return this;\n"
591 "}\n");
592 printer->Annotate("{", "}", descriptor_);
593 WriteFieldDocComment(printer, descriptor_);
594 printer->Print(variables_,
595 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
596 " java.lang.Iterable<? extends $boxed_type$> values) {\n"
597 " copyOnWrite();\n"
598 " instance.addAll$capitalized_name$(values);\n"
599 " return this;\n"
600 "}\n");
601 printer->Annotate("{", "}", descriptor_);
602 WriteFieldDocComment(printer, descriptor_);
603 printer->Print(
604 variables_,
605 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
606 " copyOnWrite();\n"
607 " instance.clear$capitalized_name$();\n"
608 " return this;\n"
609 "}\n");
610 printer->Annotate("{", "}", descriptor_);
611 }
612
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const613 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
614 io::Printer* printer, std::vector<uint16>* output) const {
615 WriteIntToUtf16CharSequence(descriptor_->number(), output);
616 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
617 output);
618 printer->Print(variables_, "\"$name$_\",\n");
619 }
620
GenerateInitializationCode(io::Printer * printer) const621 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
622 io::Printer* printer) const {
623 printer->Print(variables_, "$name$_ = $empty_list$;\n");
624 }
625
GetBoxedType() const626 std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
627 return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
628 }
629
630 } // namespace java
631 } // namespace compiler
632 } // namespace protobuf
633 } // namespace google
634