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 <google/protobuf/compiler/java/java_primitive_field_lite.h>
36
37 #include <cstdint>
38 #include <map>
39 #include <string>
40
41 #include <google/protobuf/stubs/logging.h>
42 #include <google/protobuf/stubs/common.h>
43 #include <google/protobuf/io/printer.h>
44 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/stubs/strutil.h>
46 #include <google/protobuf/compiler/java/java_context.h>
47 #include <google/protobuf/compiler/java/java_doc_comment.h>
48 #include <google/protobuf/compiler/java/java_helpers.h>
49 #include <google/protobuf/compiler/java/java_name_resolver.h>
50
51 namespace google {
52 namespace protobuf {
53 namespace compiler {
54 namespace java {
55
56 using internal::WireFormat;
57 using internal::WireFormatLite;
58
59 namespace {
EnableExperimentalRuntimeForLite()60 bool EnableExperimentalRuntimeForLite() {
61 #ifdef PROTOBUF_EXPERIMENT
62 return PROTOBUF_EXPERIMENT;
63 #else // PROTOBUF_EXPERIMENT
64 return false;
65 #endif // !PROTOBUF_EXPERIMENT
66 }
67
SetPrimitiveVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)68 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
69 int messageBitIndex, int builderBitIndex,
70 const FieldGeneratorInfo* info,
71 ClassNameResolver* name_resolver,
72 std::map<std::string, std::string>* variables) {
73 SetCommonFieldVariables(descriptor, info, variables);
74 JavaType javaType = GetJavaType(descriptor);
75 (*variables)["type"] = PrimitiveTypeName(javaType);
76 (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
77 (*variables)["kt_type"] = KotlinTypeName(javaType);
78 (*variables)["field_type"] = (*variables)["type"];
79 (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
80 (*variables)["capitalized_type"] =
81 GetCapitalizedType(descriptor, /* immutable = */ true);
82 (*variables)["tag"] =
83 StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor)));
84 (*variables)["tag_size"] = StrCat(
85 WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
86 (*variables)["required"] = descriptor->is_required() ? "true" : "false";
87
88 std::string capitalized_type = UnderscoresToCamelCase(
89 PrimitiveTypeName(javaType), true /* cap_next_letter */);
90 switch (javaType) {
91 case JAVATYPE_INT:
92 case JAVATYPE_LONG:
93 case JAVATYPE_FLOAT:
94 case JAVATYPE_DOUBLE:
95 case JAVATYPE_BOOLEAN:
96 (*variables)["field_list_type"] =
97 "com.google.protobuf.Internal." + capitalized_type + "List";
98 (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
99 (*variables)["make_name_unmodifiable"] =
100 (*variables)["name"] + "_.makeImmutable()";
101 (*variables)["repeated_get"] =
102 (*variables)["name"] + "_.get" + capitalized_type;
103 (*variables)["repeated_add"] =
104 (*variables)["name"] + "_.add" + capitalized_type;
105 (*variables)["repeated_set"] =
106 (*variables)["name"] + "_.set" + capitalized_type;
107 (*variables)["visit_type"] = capitalized_type;
108 (*variables)["visit_type_list"] = "visit" + capitalized_type + "List";
109 break;
110 default:
111 (*variables)["field_list_type"] =
112 "com.google.protobuf.Internal.ProtobufList<" +
113 (*variables)["boxed_type"] + ">";
114 (*variables)["empty_list"] = "emptyProtobufList()";
115 (*variables)["make_name_unmodifiable"] =
116 (*variables)["name"] + "_.makeImmutable()";
117 (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
118 (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
119 (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
120 (*variables)["visit_type"] = "ByteString";
121 (*variables)["visit_type_list"] = "visitList";
122 }
123
124 if (javaType == JAVATYPE_BYTES) {
125 (*variables)["bytes_default"] =
126 ToUpper((*variables)["name"]) + "_DEFAULT_VALUE";
127 }
128
129 if (IsReferenceType(javaType)) {
130 // We use `x.getClass()` as a null check because it generates less bytecode
131 // than an `if (x == null) { throw ... }` statement.
132 (*variables)["null_check"] =
133 " java.lang.Class<?> valueClass = value.getClass();\n";
134 } else {
135 (*variables)["null_check"] = "";
136 }
137 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
138 // by the proto compiler
139 (*variables)["deprecation"] =
140 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
141 (*variables)["kt_deprecation"] =
142 descriptor->options().deprecated()
143 ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
144 " is deprecated\") "
145 : "";
146 int fixed_size = FixedSize(GetType(descriptor));
147 if (fixed_size != -1) {
148 (*variables)["fixed_size"] = StrCat(fixed_size);
149 }
150
151 if (HasHasbit(descriptor)) {
152 // For singular messages and builders, one bit is used for the hasField bit.
153 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
154
155 // Note that these have a trailing ";".
156 (*variables)["set_has_field_bit_message"] =
157 GenerateSetBit(messageBitIndex) + ";";
158 (*variables)["clear_has_field_bit_message"] =
159 GenerateClearBit(messageBitIndex) + ";";
160
161 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
162 } else {
163 (*variables)["set_has_field_bit_message"] = "";
164 (*variables)["clear_has_field_bit_message"] = "";
165
166 switch (descriptor->type()) {
167 case FieldDescriptor::TYPE_BYTES:
168 (*variables)["is_field_present_message"] =
169 "!" + (*variables)["name"] + "_.isEmpty()";
170 break;
171 case FieldDescriptor::TYPE_FLOAT:
172 (*variables)["is_field_present_message"] =
173 "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] +
174 "_) != 0";
175 break;
176 case FieldDescriptor::TYPE_DOUBLE:
177 (*variables)["is_field_present_message"] =
178 "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] +
179 "_) != 0";
180 break;
181 default:
182 (*variables)["is_field_present_message"] =
183 (*variables)["name"] + "_ != " + (*variables)["default"];
184 break;
185 }
186 }
187
188 (*variables)["get_has_field_bit_from_local"] =
189 GenerateGetBitFromLocal(builderBitIndex);
190 (*variables)["set_has_field_bit_to_local"] =
191 GenerateSetBitToLocal(messageBitIndex);
192 }
193
194 } // namespace
195
196 // ===================================================================
197
ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)198 ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
199 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
200 : descriptor_(descriptor),
201 messageBitIndex_(messageBitIndex),
202 name_resolver_(context->GetNameResolver()) {
203 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
204 context->GetFieldGeneratorInfo(descriptor),
205 name_resolver_, &variables_);
206 }
207
~ImmutablePrimitiveFieldLiteGenerator()208 ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
209
GetNumBitsForMessage() const210 int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
211 return HasHasbit(descriptor_) ? 1 : 0;
212 }
213
GenerateInterfaceMembers(io::Printer * printer) const214 void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
215 io::Printer* printer) const {
216 if (HasHazzer(descriptor_)) {
217 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
218 printer->Print(variables_,
219 "$deprecation$boolean has$capitalized_name$();\n");
220 }
221 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
222 printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
223 }
224
GenerateMembers(io::Printer * printer) const225 void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
226 io::Printer* printer) const {
227 if (IsByteStringWithCustomDefaultValue(descriptor_)) {
228 // allocate this once statically since we know ByteStrings are immutable
229 // values that can be reused.
230 printer->Print(
231 variables_,
232 "private static final $field_type$ $bytes_default$ = $default$;\n");
233 }
234 printer->Print(variables_, "private $field_type$ $name$_;\n");
235 PrintExtraFieldInfo(variables_, printer);
236 if (HasHazzer(descriptor_)) {
237 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
238 printer->Print(
239 variables_,
240 "@java.lang.Override\n"
241 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
242 " return $get_has_field_bit_message$;\n"
243 "}\n");
244 printer->Annotate("{", "}", descriptor_);
245 }
246
247 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
248 printer->Print(variables_,
249 "@java.lang.Override\n"
250 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
251 " return $name$_;\n"
252 "}\n");
253 printer->Annotate("{", "}", descriptor_);
254
255 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
256 printer->Print(variables_,
257 "private void set$capitalized_name$($type$ value) {\n"
258 "$null_check$"
259 " $set_has_field_bit_message$\n"
260 " $name$_ = value;\n"
261 "}\n");
262
263 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
264 printer->Print(variables_,
265 "private void clear$capitalized_name$() {\n"
266 " $clear_has_field_bit_message$\n");
267 JavaType type = GetJavaType(descriptor_);
268 if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
269 // The default value is not a simple literal so we want to avoid executing
270 // it multiple times. Instead, get the default out of the default instance.
271 printer->Print(
272 variables_,
273 " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
274 } else {
275 printer->Print(variables_, " $name$_ = $default$;\n");
276 }
277 printer->Print(variables_, "}\n");
278 }
279
GenerateBuilderMembers(io::Printer * printer) const280 void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
281 io::Printer* printer) const {
282 if (HasHazzer(descriptor_)) {
283 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
284 printer->Print(
285 variables_,
286 "@java.lang.Override\n"
287 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
288 " return instance.has$capitalized_name$();\n"
289 "}\n");
290 printer->Annotate("{", "}", descriptor_);
291 }
292
293 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
294 printer->Print(variables_,
295 "@java.lang.Override\n"
296 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
297 " return instance.get$capitalized_name$();\n"
298 "}\n");
299 printer->Annotate("{", "}", descriptor_);
300
301 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
302 /* builder */ true);
303 printer->Print(variables_,
304 "$deprecation$public Builder "
305 "${$set$capitalized_name$$}$($type$ value) {\n"
306 " copyOnWrite();\n"
307 " instance.set$capitalized_name$(value);\n"
308 " return this;\n"
309 "}\n");
310 printer->Annotate("{", "}", descriptor_);
311
312 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
313 /* builder */ true);
314 printer->Print(
315 variables_,
316 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
317 " copyOnWrite();\n"
318 " instance.clear$capitalized_name$();\n"
319 " return this;\n"
320 "}\n");
321 printer->Annotate("{", "}", descriptor_);
322 }
323
GenerateKotlinDslMembers(io::Printer * printer) const324 void ImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
325 io::Printer* printer) const {
326 WriteFieldDocComment(printer, descriptor_);
327 printer->Print(variables_,
328 "$kt_deprecation$public var $kt_name$: $kt_type$\n"
329 " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
330 " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
331 " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
332 " set(value) {\n"
333 " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
334 " }\n");
335
336 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
337 /* builder */ false);
338 printer->Print(variables_,
339 "public fun ${$clear$kt_capitalized_name$$}$() {\n"
340 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
341 "}\n");
342
343 if (HasHazzer(descriptor_)) {
344 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
345 printer->Print(
346 variables_,
347 "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
348 " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
349 "}\n");
350 }
351 }
352
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const353 void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
354 io::Printer* printer, std::vector<uint16_t>* output) const {
355 WriteIntToUtf16CharSequence(descriptor_->number(), output);
356 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
357 output);
358 if (HasHasbit(descriptor_)) {
359 WriteIntToUtf16CharSequence(messageBitIndex_, output);
360 }
361 printer->Print(variables_, "\"$name$_\",\n");
362 }
363
GenerateInitializationCode(io::Printer * printer) const364 void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
365 io::Printer* printer) const {
366 if (IsByteStringWithCustomDefaultValue(descriptor_)) {
367 printer->Print(variables_, "$name$_ = $bytes_default$;\n");
368 } else if (!IsDefaultValueJavaDefault(descriptor_)) {
369 printer->Print(variables_, "$name$_ = $default$;\n");
370 }
371 }
372
GetBoxedType() const373 std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
374 return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
375 }
376
377 // ===================================================================
378
379 ImmutablePrimitiveOneofFieldLiteGenerator::
ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)380 ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
381 int messageBitIndex,
382 Context* context)
383 : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
384 context) {
385 const OneofGeneratorInfo* info =
386 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
387 SetCommonOneofVariables(descriptor, info, &variables_);
388 }
389
390 ImmutablePrimitiveOneofFieldLiteGenerator::
~ImmutablePrimitiveOneofFieldLiteGenerator()391 ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
392
GenerateMembers(io::Printer * printer) const393 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers(
394 io::Printer* printer) const {
395 PrintExtraFieldInfo(variables_, printer);
396 GOOGLE_DCHECK(HasHazzer(descriptor_));
397 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
398 printer->Print(variables_,
399 "@java.lang.Override\n"
400 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
401 " return $has_oneof_case_message$;\n"
402 "}\n");
403 printer->Annotate("{", "}", descriptor_);
404
405 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
406 printer->Print(variables_,
407 "@java.lang.Override\n"
408 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
409 " if ($has_oneof_case_message$) {\n"
410 " return ($boxed_type$) $oneof_name$_;\n"
411 " }\n"
412 " return $default$;\n"
413 "}\n");
414 printer->Annotate("{", "}", descriptor_);
415
416 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
417 printer->Print(variables_,
418 "private void set$capitalized_name$($type$ value) {\n"
419 "$null_check$"
420 " $set_oneof_case_message$;\n"
421 " $oneof_name$_ = value;\n"
422 "}\n");
423
424 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
425 printer->Print(variables_,
426 "private void clear$capitalized_name$() {\n"
427 " if ($has_oneof_case_message$) {\n"
428 " $clear_oneof_case_message$;\n"
429 " $oneof_name$_ = null;\n"
430 " }\n"
431 "}\n");
432 }
433
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const434 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo(
435 io::Printer* printer, std::vector<uint16_t>* output) const {
436 WriteIntToUtf16CharSequence(descriptor_->number(), output);
437 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
438 output);
439 WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
440 }
441
GenerateBuilderMembers(io::Printer * printer) const442 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers(
443 io::Printer* printer) const {
444 GOOGLE_DCHECK(HasHazzer(descriptor_));
445 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
446 printer->Print(variables_,
447 "@java.lang.Override\n"
448 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
449 " return instance.has$capitalized_name$();\n"
450 "}\n");
451 printer->Annotate("{", "}", descriptor_);
452
453 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
454 printer->Print(variables_,
455 "@java.lang.Override\n"
456 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
457 " return instance.get$capitalized_name$();\n"
458 "}\n");
459 printer->Annotate("{", "}", descriptor_);
460
461 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
462 /* builder */ true);
463 printer->Print(variables_,
464 "$deprecation$public Builder "
465 "${$set$capitalized_name$$}$($type$ value) {\n"
466 " copyOnWrite();\n"
467 " instance.set$capitalized_name$(value);\n"
468 " return this;\n"
469 "}\n");
470 printer->Annotate("{", "}", descriptor_);
471
472 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
473 /* builder */ true);
474 printer->Print(
475 variables_,
476 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
477 " copyOnWrite();\n"
478 " instance.clear$capitalized_name$();\n"
479 " return this;\n"
480 "}\n");
481 printer->Annotate("{", "}", descriptor_);
482 }
483
484 // ===================================================================
485
486 RepeatedImmutablePrimitiveFieldLiteGenerator::
RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)487 RepeatedImmutablePrimitiveFieldLiteGenerator(
488 const FieldDescriptor* descriptor, int messageBitIndex,
489 Context* context)
490 : descriptor_(descriptor),
491 context_(context),
492 name_resolver_(context->GetNameResolver()) {
493 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
494 context->GetFieldGeneratorInfo(descriptor),
495 name_resolver_, &variables_);
496 }
497
498 RepeatedImmutablePrimitiveFieldLiteGenerator::
~RepeatedImmutablePrimitiveFieldLiteGenerator()499 ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
500
GetNumBitsForMessage() const501 int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
502 return 0;
503 }
504
GenerateInterfaceMembers(io::Printer * printer) const505 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
506 io::Printer* printer) const {
507 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
508 printer->Print(variables_,
509 "$deprecation$java.util.List<$boxed_type$> "
510 "get$capitalized_name$List();\n");
511 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
512 printer->Print(variables_,
513 "$deprecation$int get$capitalized_name$Count();\n");
514 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
515 printer->Print(variables_,
516 "$deprecation$$type$ get$capitalized_name$(int index);\n");
517 }
518
GenerateMembers(io::Printer * printer) const519 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
520 io::Printer* printer) const {
521 printer->Print(variables_, "private $field_list_type$ $name$_;\n");
522 PrintExtraFieldInfo(variables_, printer);
523 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
524 printer->Print(variables_,
525 "@java.lang.Override\n"
526 "$deprecation$public java.util.List<$boxed_type$>\n"
527 " ${$get$capitalized_name$List$}$() {\n"
528 " return $name$_;\n" // note: unmodifiable list
529 "}\n");
530 printer->Annotate("{", "}", descriptor_);
531 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
532 printer->Print(
533 variables_,
534 "@java.lang.Override\n"
535 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
536 " return $name$_.size();\n"
537 "}\n");
538 printer->Annotate("{", "}", descriptor_);
539 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
540 printer->Print(
541 variables_,
542 "@java.lang.Override\n"
543 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
544 " return $repeated_get$(index);\n"
545 "}\n");
546 printer->Annotate("{", "}", descriptor_);
547
548 if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
549 context_->HasGeneratedMethods(descriptor_->containing_type())) {
550 printer->Print(variables_,
551 "private int $name$MemoizedSerializedSize = -1;\n");
552 }
553
554 printer->Print(
555 variables_,
556 "private void ensure$capitalized_name$IsMutable() {\n"
557 // Use a temporary to avoid a redundant iget-object.
558 " $field_list_type$ tmp = $name$_;\n"
559 " if (!tmp.isModifiable()) {\n"
560 " $name$_ =\n"
561 " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
562 " }\n"
563 "}\n");
564
565 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
566 printer->Print(variables_,
567 "private void set$capitalized_name$(\n"
568 " int index, $type$ value) {\n"
569 "$null_check$"
570 " ensure$capitalized_name$IsMutable();\n"
571 " $repeated_set$(index, value);\n"
572 "}\n");
573 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
574 printer->Print(variables_,
575 "private void add$capitalized_name$($type$ value) {\n"
576 "$null_check$"
577 " ensure$capitalized_name$IsMutable();\n"
578 " $repeated_add$(value);\n"
579 "}\n");
580 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
581 printer->Print(variables_,
582 "private void addAll$capitalized_name$(\n"
583 " java.lang.Iterable<? extends $boxed_type$> values) {\n"
584 " ensure$capitalized_name$IsMutable();\n"
585 " com.google.protobuf.AbstractMessageLite.addAll(\n"
586 " values, $name$_);\n"
587 "}\n");
588 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
589 printer->Print(variables_,
590 "private void clear$capitalized_name$() {\n"
591 " $name$_ = $empty_list$;\n"
592 "}\n");
593 }
594
GenerateBuilderMembers(io::Printer * printer) const595 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
596 io::Printer* printer) const {
597 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
598 printer->Print(variables_,
599 "@java.lang.Override\n"
600 "$deprecation$public java.util.List<$boxed_type$>\n"
601 " ${$get$capitalized_name$List$}$() {\n"
602 " return java.util.Collections.unmodifiableList(\n"
603 " instance.get$capitalized_name$List());\n"
604 "}\n");
605 printer->Annotate("{", "}", descriptor_);
606 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
607 printer->Print(
608 variables_,
609 "@java.lang.Override\n"
610 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
611 " return instance.get$capitalized_name$Count();\n"
612 "}\n");
613 printer->Annotate("{", "}", descriptor_);
614 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
615 printer->Print(
616 variables_,
617 "@java.lang.Override\n"
618 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
619 " return instance.get$capitalized_name$(index);\n"
620 "}\n");
621 printer->Annotate("{", "}", descriptor_);
622 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
623 /* builder */ true);
624 printer->Print(variables_,
625 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
626 " int index, $type$ value) {\n"
627 " copyOnWrite();\n"
628 " instance.set$capitalized_name$(index, value);\n"
629 " return this;\n"
630 "}\n");
631 printer->Annotate("{", "}", descriptor_);
632 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
633 /* builder */ true);
634 printer->Print(variables_,
635 "$deprecation$public Builder "
636 "${$add$capitalized_name$$}$($type$ value) {\n"
637 " copyOnWrite();\n"
638 " instance.add$capitalized_name$(value);\n"
639 " return this;\n"
640 "}\n");
641 printer->Annotate("{", "}", descriptor_);
642 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
643 /* builder */ true);
644 printer->Print(variables_,
645 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
646 " java.lang.Iterable<? extends $boxed_type$> values) {\n"
647 " copyOnWrite();\n"
648 " instance.addAll$capitalized_name$(values);\n"
649 " return this;\n"
650 "}\n");
651 printer->Annotate("{", "}", descriptor_);
652 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
653 /* builder */ true);
654 printer->Print(
655 variables_,
656 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
657 " copyOnWrite();\n"
658 " instance.clear$capitalized_name$();\n"
659 " return this;\n"
660 "}\n");
661 printer->Annotate("{", "}", descriptor_);
662 }
663
GenerateKotlinDslMembers(io::Printer * printer) const664 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
665 io::Printer* printer) const {
666 printer->Print(
667 variables_,
668 "/**\n"
669 " * An uninstantiable, behaviorless type to represent the field in\n"
670 " * generics.\n"
671 " */\n"
672 "@kotlin.OptIn"
673 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
674 "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
675 " : com.google.protobuf.kotlin.DslProxy()\n");
676
677 WriteFieldDocComment(printer, descriptor_);
678 printer->Print(variables_,
679 "$kt_deprecation$ public val $kt_name$: "
680 "com.google.protobuf.kotlin.DslList"
681 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
682 " @kotlin.jvm.JvmSynthetic\n"
683 " get() = com.google.protobuf.kotlin.DslList(\n"
684 " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
685 " )\n");
686
687 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
688 /* builder */ false);
689 printer->Print(variables_,
690 "@kotlin.jvm.JvmSynthetic\n"
691 "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
692 "public fun com.google.protobuf.kotlin.DslList"
693 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
694 "add(value: $kt_type$) {\n"
695 " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
696 "}");
697
698 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
699 /* builder */ false);
700 printer->Print(variables_,
701 "@kotlin.jvm.JvmSynthetic\n"
702 "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
703 "@Suppress(\"NOTHING_TO_INLINE\")\n"
704 "public inline operator fun com.google.protobuf.kotlin.DslList"
705 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
706 "plusAssign(value: $kt_type$) {\n"
707 " add(value)\n"
708 "}");
709
710 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
711 /* builder */ false);
712 printer->Print(variables_,
713 "@kotlin.jvm.JvmSynthetic\n"
714 "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
715 "public fun com.google.protobuf.kotlin.DslList"
716 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
717 "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
718 " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
719 "}");
720
721 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
722 /* builder */ false);
723 printer->Print(
724 variables_,
725 "@kotlin.jvm.JvmSynthetic\n"
726 "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
727 "@Suppress(\"NOTHING_TO_INLINE\")\n"
728 "public inline operator fun com.google.protobuf.kotlin.DslList"
729 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
730 "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
731 " addAll(values)\n"
732 "}");
733
734 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
735 /* builder */ false);
736 printer->Print(
737 variables_,
738 "@kotlin.jvm.JvmSynthetic\n"
739 "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
740 "public operator fun com.google.protobuf.kotlin.DslList"
741 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
742 "set(index: kotlin.Int, value: $kt_type$) {\n"
743 " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
744 "}");
745
746 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
747 /* builder */ false);
748 printer->Print(variables_,
749 "@kotlin.jvm.JvmSynthetic\n"
750 "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
751 "public fun com.google.protobuf.kotlin.DslList"
752 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
753 "clear() {\n"
754 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
755 "}");
756 }
757
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const758 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
759 io::Printer* printer, std::vector<uint16_t>* output) const {
760 WriteIntToUtf16CharSequence(descriptor_->number(), output);
761 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
762 output);
763 printer->Print(variables_, "\"$name$_\",\n");
764 }
765
GenerateInitializationCode(io::Printer * printer) const766 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
767 io::Printer* printer) const {
768 printer->Print(variables_, "$name$_ = $empty_list$;\n");
769 }
770
GetBoxedType() const771 std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
772 return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
773 }
774
775 } // namespace java
776 } // namespace compiler
777 } // namespace protobuf
778 } // namespace google
779