1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: kenton@google.com (Kenton Varda)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include "google/protobuf/compiler/java/lite/primitive_field.h"
13
14 #include <cstdint>
15 #include <string>
16
17 #include "absl/log/absl_check.h"
18 #include "absl/strings/ascii.h"
19 #include "absl/strings/str_cat.h"
20 #include "google/protobuf/compiler/java/context.h"
21 #include "google/protobuf/compiler/java/doc_comment.h"
22 #include "google/protobuf/compiler/java/field_common.h"
23 #include "google/protobuf/compiler/java/helpers.h"
24 #include "google/protobuf/compiler/java/internal_helpers.h"
25 #include "google/protobuf/compiler/java/name_resolver.h"
26 #include "google/protobuf/wire_format.h"
27
28 namespace google {
29 namespace protobuf {
30 namespace compiler {
31 namespace java {
32
33 using internal::WireFormat;
34 using internal::WireFormatLite;
35 using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
36
37 namespace {
EnableExperimentalRuntimeForLite()38 bool EnableExperimentalRuntimeForLite() {
39 #ifdef PROTOBUF_EXPERIMENT
40 return PROTOBUF_EXPERIMENT;
41 #else // PROTOBUF_EXPERIMENT
42 return false;
43 #endif // !PROTOBUF_EXPERIMENT
44 }
45
SetPrimitiveVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,absl::flat_hash_map<absl::string_view,std::string> * variables,Context * context)46 void SetPrimitiveVariables(
47 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
48 const FieldGeneratorInfo* info, ClassNameResolver* name_resolver,
49 absl::flat_hash_map<absl::string_view, std::string>* variables,
50 Context* context) {
51 SetCommonFieldVariables(descriptor, info, variables);
52 JavaType javaType = GetJavaType(descriptor);
53 (*variables)["type"] = std::string(PrimitiveTypeName(javaType));
54 (*variables)["boxed_type"] = std::string(BoxedPrimitiveTypeName(javaType));
55 (*variables)["kt_type"] = std::string(KotlinTypeName(javaType));
56 variables->insert({"field_type", (*variables)["type"]});
57 (*variables)["default"] =
58 ImmutableDefaultValue(descriptor, name_resolver, context->options());
59 (*variables)["capitalized_type"] = std::string(GetCapitalizedType(
60 descriptor, /* immutable = */ true, context->options()));
61 (*variables)["tag"] =
62 absl::StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor)));
63 (*variables)["tag_size"] = absl::StrCat(
64 WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
65 (*variables)["required"] = descriptor->is_required() ? "true" : "false";
66
67 std::string capitalized_type = UnderscoresToCamelCase(
68 PrimitiveTypeName(javaType), true /* cap_next_letter */);
69 std::string name = (*variables)["name"];
70 switch (javaType) {
71 case JAVATYPE_INT:
72 case JAVATYPE_LONG:
73 case JAVATYPE_FLOAT:
74 case JAVATYPE_DOUBLE:
75 case JAVATYPE_BOOLEAN:
76 (*variables)["field_list_type"] = absl::StrCat(
77 "com.google.protobuf.Internal.", capitalized_type, "List");
78 (*variables)["empty_list"] =
79 absl::StrCat("empty", capitalized_type, "List()");
80 (*variables)["make_name_unmodifiable"] =
81 absl::StrCat(name, "_.makeImmutable()");
82 (*variables)["repeated_get"] =
83 absl::StrCat(name, "_.get", capitalized_type);
84 (*variables)["repeated_add"] =
85 absl::StrCat(name, "_.add", capitalized_type);
86 (*variables)["repeated_set"] =
87 absl::StrCat(name, "_.set", capitalized_type);
88 (*variables)["visit_type"] = capitalized_type;
89 (*variables)["visit_type_list"] =
90 absl::StrCat("visit", capitalized_type, "List");
91 break;
92 default:
93 variables->insert(
94 {"field_list_type",
95 absl::StrCat("com.google.protobuf.Internal.ProtobufList<",
96 (*variables)["boxed_type"], ">")});
97 (*variables)["empty_list"] = "emptyProtobufList()";
98 (*variables)["make_name_unmodifiable"] =
99 absl::StrCat(name, "_.makeImmutable()");
100 (*variables)["repeated_get"] = absl::StrCat(name, "_.get");
101 (*variables)["repeated_add"] = absl::StrCat(name, "_.add");
102 (*variables)["repeated_set"] = absl::StrCat(name, "_.set");
103 (*variables)["visit_type"] = "ByteString";
104 (*variables)["visit_type_list"] = "visitList";
105 }
106
107 if (javaType == JAVATYPE_BYTES) {
108 (*variables)["bytes_default"] =
109 absl::StrCat(absl::AsciiStrToUpper(name), "_DEFAULT_VALUE");
110 }
111
112 if (IsReferenceType(javaType)) {
113 // We use `x.getClass()` as a null check because it generates less bytecode
114 // than an `if (x == null) { throw ... }` statement.
115 (*variables)["null_check"] =
116 " java.lang.Class<?> valueClass = value.getClass();\n";
117 } else {
118 (*variables)["null_check"] = "";
119 }
120 // TODO: Add @deprecated javadoc when generating javadoc is supported
121 // by the proto compiler
122 (*variables)["deprecation"] =
123 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
124 (*variables)["kt_deprecation"] =
125 descriptor->options().deprecated()
126 ? absl::StrCat("@kotlin.Deprecated(message = \"Field ", name,
127 " is deprecated\") ")
128 : "";
129 int fixed_size = FixedSize(GetType(descriptor));
130 if (fixed_size != -1) {
131 (*variables)["fixed_size"] = absl::StrCat(fixed_size);
132 }
133
134 if (HasHasbit(descriptor)) {
135 // For singular messages and builders, one bit is used for the hasField bit.
136 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
137
138 // Note that these have a trailing ";".
139 (*variables)["set_has_field_bit_message"] =
140 absl::StrCat(GenerateSetBit(messageBitIndex), ";");
141 (*variables)["clear_has_field_bit_message"] =
142 absl::StrCat(GenerateClearBit(messageBitIndex), ";");
143
144 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
145 } else {
146 (*variables)["set_has_field_bit_message"] = "";
147 (*variables)["clear_has_field_bit_message"] = "";
148
149 switch (descriptor->type()) {
150 case FieldDescriptor::TYPE_BYTES:
151 (*variables)["is_field_present_message"] =
152 absl::StrCat("!", name, "_.isEmpty()");
153 break;
154 case FieldDescriptor::TYPE_FLOAT:
155 (*variables)["is_field_present_message"] =
156 absl::StrCat("java.lang.Float.floatToRawIntBits(", name, "_) != 0");
157 break;
158 case FieldDescriptor::TYPE_DOUBLE:
159 (*variables)["is_field_present_message"] = absl::StrCat(
160 "java.lang.Double.doubleToRawLongBits(", name, "_) != 0");
161 break;
162 default:
163 variables->insert(
164 {"is_field_present_message",
165 absl::StrCat(name, "_ != ", (*variables)["default"])});
166 break;
167 }
168 }
169
170 // Annotations often use { and } variables to denote ranges.
171 (*variables)["{"] = "";
172 (*variables)["}"] = "";
173 }
174
175 } // namespace
176
177 // ===================================================================
178
ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)179 ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
180 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
181 : descriptor_(descriptor),
182 messageBitIndex_(messageBitIndex),
183 context_(context),
184 name_resolver_(context->GetNameResolver()) {
185 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
186 context->GetFieldGeneratorInfo(descriptor),
187 name_resolver_, &variables_, context);
188 }
189
~ImmutablePrimitiveFieldLiteGenerator()190 ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
191
GetNumBitsForMessage() const192 int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
193 return HasHasbit(descriptor_) ? 1 : 0;
194 }
195
GenerateInterfaceMembers(io::Printer * printer) const196 void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
197 io::Printer* printer) const {
198 if (descriptor_->has_presence()) {
199 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
200 context_->options());
201 printer->Print(variables_,
202 "$deprecation$boolean has$capitalized_name$();\n");
203 }
204 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
205 context_->options());
206 printer->Print(variables_,
207 "$deprecation$$type$ ${$get$capitalized_name$$}$();\n");
208 printer->Annotate("{", "}", descriptor_);
209 }
210
GenerateMembers(io::Printer * printer) const211 void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
212 io::Printer* printer) const {
213 if (IsByteStringWithCustomDefaultValue(descriptor_)) {
214 // allocate this once statically since we know ByteStrings are immutable
215 // values that can be reused.
216 printer->Print(
217 variables_,
218 "private static final $field_type$ $bytes_default$ = $default$;\n");
219 }
220 if (!context_->options().opensource_runtime) {
221 printer->Print(variables_,
222 "@com.google.protobuf.ProtoField(\n"
223 " isRequired=$required$)\n");
224 if (HasHasbit(descriptor_)) {
225 printer->Print(variables_,
226 "@com.google.protobuf.ProtoPresenceCheckedField(\n"
227 " presenceBitsId=$bit_field_id$,\n"
228 " mask=$bit_field_mask$)\n");
229 }
230 }
231 printer->Print(variables_, "private $field_type$ $name$_;\n");
232 PrintExtraFieldInfo(variables_, printer);
233 if (descriptor_->has_presence()) {
234 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
235 context_->options());
236 printer->Print(
237 variables_,
238 "@java.lang.Override\n"
239 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
240 " return $get_has_field_bit_message$;\n"
241 "}\n");
242 printer->Annotate("{", "}", descriptor_);
243 }
244
245 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
246 context_->options());
247 printer->Print(variables_,
248 "@java.lang.Override\n"
249 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
250 " return $name$_;\n"
251 "}\n");
252 printer->Annotate("{", "}", descriptor_);
253
254 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
255 context_->options());
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 context_->options());
265 printer->Print(variables_,
266 "private void clear$capitalized_name$() {\n"
267 " $clear_has_field_bit_message$\n");
268 JavaType type = GetJavaType(descriptor_);
269 if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
270 // The default value is not a simple literal so we want to avoid executing
271 // it multiple times. Instead, get the default out of the default instance.
272 printer->Print(
273 variables_,
274 " $name$_ = getDefaultInstance().get$capitalized_name$();\n");
275 } else {
276 printer->Print(variables_, " $name$_ = $default$;\n");
277 }
278 printer->Print(variables_, "}\n");
279 }
280
GenerateBuilderMembers(io::Printer * printer) const281 void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
282 io::Printer* printer) const {
283 if (descriptor_->has_presence()) {
284 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
285 context_->options());
286 printer->Print(
287 variables_,
288 "@java.lang.Override\n"
289 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
290 " return instance.has$capitalized_name$();\n"
291 "}\n");
292 printer->Annotate("{", "}", descriptor_);
293 }
294
295 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
296 context_->options());
297 printer->Print(variables_,
298 "@java.lang.Override\n"
299 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
300 " return instance.get$capitalized_name$();\n"
301 "}\n");
302 printer->Annotate("{", "}", descriptor_);
303
304 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
305 context_->options(),
306 /* builder */ true);
307 printer->Print(variables_,
308 "$deprecation$public Builder "
309 "${$set$capitalized_name$$}$($type$ value) {\n"
310 " copyOnWrite();\n"
311 " instance.set$capitalized_name$(value);\n"
312 " return this;\n"
313 "}\n");
314 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
315
316 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
317 context_->options(),
318 /* builder */ true);
319 printer->Print(
320 variables_,
321 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
322 " copyOnWrite();\n"
323 " instance.clear$capitalized_name$();\n"
324 " return this;\n"
325 "}\n");
326 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
327 }
328
GenerateKotlinDslMembers(io::Printer * printer) const329 void ImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
330 io::Printer* printer) const {
331 auto vars = printer->WithVars(variables_);
332 JvmNameContext name_ctx = {context_->options(), printer};
333 WriteFieldDocComment(printer, descriptor_, context_->options());
334 if (descriptor_->name() == "is_initialized") {
335 printer->Emit(
336 {
337 {"jvm_name_get",
338 [&] { JvmName("${$get$kt_capitalized_name$$}$", name_ctx); }},
339 {"jvm_name_set",
340 [&] { JvmName("${$set$kt_capitalized_name$$}$", name_ctx); }},
341 },
342 "// TODO: b/336400327 - remove this hack; we should access properties\n"
343 "$kt_deprecation$public var $kt_name$: $kt_type$\n"
344 " $jvm_name_get$"
345 " get() = $kt_dsl_builder$.get${$$kt_capitalized_name$$}$()\n"
346 " $jvm_name_set$"
347 " set(value) {\n"
348 " $kt_dsl_builder$.${$set$kt_capitalized_name$$}$(value)\n"
349 " }\n");
350 } else {
351 printer->Emit(
352 {
353 {"jvm_name_get",
354 [&] { JvmName("${$get$kt_capitalized_name$$}$", name_ctx); }},
355 {"jvm_name_set",
356 [&] { JvmName("${$set$kt_capitalized_name$$}$", name_ctx); }},
357 },
358 "$kt_deprecation$public var $kt_name$: $kt_type$\n"
359 " $jvm_name_get$"
360 " get() = $kt_dsl_builder$.${$$kt_safe_name$$}$\n"
361 " $jvm_name_set$"
362 " set(value) {\n"
363 " $kt_dsl_builder$.${$$kt_safe_name$$}$ = value\n"
364 " }\n");
365 }
366
367 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
368 context_->options(),
369 /* builder */ false, /* kdoc */ true);
370 printer->Print(
371 "public fun ${$clear$kt_capitalized_name$$}$() {\n"
372 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
373 "}\n");
374
375 if (descriptor_->has_presence()) {
376 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
377 context_->options(),
378 /* builder */ false, /* kdoc */ true);
379 printer->Print(
380 "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
381 " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
382 "}\n");
383 }
384 }
385
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const386 void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
387 io::Printer* printer, std::vector<uint16_t>* output) const {
388 WriteIntToUtf16CharSequence(descriptor_->number(), output);
389 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
390 output);
391 if (HasHasbit(descriptor_)) {
392 WriteIntToUtf16CharSequence(messageBitIndex_, output);
393 }
394 printer->Print(variables_, "\"$name$_\",\n");
395 }
396
GenerateInitializationCode(io::Printer * printer) const397 void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
398 io::Printer* printer) const {
399 if (IsByteStringWithCustomDefaultValue(descriptor_)) {
400 printer->Print(variables_, "$name$_ = $bytes_default$;\n");
401 } else if (!IsDefaultValueJavaDefault(descriptor_)) {
402 printer->Print(variables_, "$name$_ = $default$;\n");
403 }
404 }
405
GetBoxedType() const406 std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
407 return std::string(BoxedPrimitiveTypeName(GetJavaType(descriptor_)));
408 }
409
410 // ===================================================================
411
412 ImmutablePrimitiveOneofFieldLiteGenerator::
ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)413 ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
414 int messageBitIndex,
415 Context* context)
416 : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
417 context) {
418 const OneofGeneratorInfo* info =
419 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
420 SetCommonOneofVariables(descriptor, info, &variables_);
421 }
422
423 ImmutablePrimitiveOneofFieldLiteGenerator::
~ImmutablePrimitiveOneofFieldLiteGenerator()424 ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
425
GenerateMembers(io::Printer * printer) const426 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers(
427 io::Printer* printer) const {
428 PrintExtraFieldInfo(variables_, printer);
429 ABSL_DCHECK(descriptor_->has_presence());
430 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
431 context_->options());
432 printer->Print(variables_,
433 "@java.lang.Override\n"
434 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
435 " return $has_oneof_case_message$;\n"
436 "}\n");
437 printer->Annotate("{", "}", descriptor_);
438
439 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
440 context_->options());
441 printer->Print(variables_,
442 "@java.lang.Override\n"
443 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
444 " if ($has_oneof_case_message$) {\n"
445 " return ($boxed_type$) $oneof_name$_;\n"
446 " }\n"
447 " return $default$;\n"
448 "}\n");
449 printer->Annotate("{", "}", descriptor_);
450
451 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
452 context_->options());
453 printer->Print(variables_,
454 "private void set$capitalized_name$($type$ value) {\n"
455 "$null_check$"
456 " $set_oneof_case_message$;\n"
457 " $oneof_name$_ = value;\n"
458 "}\n");
459
460 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
461 context_->options());
462 printer->Print(variables_,
463 "private void clear$capitalized_name$() {\n"
464 " if ($has_oneof_case_message$) {\n"
465 " $clear_oneof_case_message$;\n"
466 " $oneof_name$_ = null;\n"
467 " }\n"
468 "}\n");
469 }
470
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const471 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo(
472 io::Printer* printer, std::vector<uint16_t>* output) const {
473 WriteIntToUtf16CharSequence(descriptor_->number(), output);
474 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
475 output);
476 WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
477 }
478
GenerateBuilderMembers(io::Printer * printer) const479 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers(
480 io::Printer* printer) const {
481 ABSL_DCHECK(descriptor_->has_presence());
482 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
483 context_->options());
484 printer->Print(variables_,
485 "@java.lang.Override\n"
486 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
487 " return instance.has$capitalized_name$();\n"
488 "}\n");
489 printer->Annotate("{", "}", descriptor_);
490
491 WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
492 context_->options());
493 printer->Print(variables_,
494 "@java.lang.Override\n"
495 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
496 " return instance.get$capitalized_name$();\n"
497 "}\n");
498 printer->Annotate("{", "}", descriptor_);
499
500 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
501 context_->options(),
502 /* builder */ true);
503 printer->Print(variables_,
504 "$deprecation$public Builder "
505 "${$set$capitalized_name$$}$($type$ value) {\n"
506 " copyOnWrite();\n"
507 " instance.set$capitalized_name$(value);\n"
508 " return this;\n"
509 "}\n");
510 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
511
512 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
513 context_->options(),
514 /* builder */ true);
515 printer->Print(
516 variables_,
517 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
518 " copyOnWrite();\n"
519 " instance.clear$capitalized_name$();\n"
520 " return this;\n"
521 "}\n");
522 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
523 }
524
525 // ===================================================================
526
527 RepeatedImmutablePrimitiveFieldLiteGenerator::
RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)528 RepeatedImmutablePrimitiveFieldLiteGenerator(
529 const FieldDescriptor* descriptor, int messageBitIndex,
530 Context* context)
531 : descriptor_(descriptor),
532 context_(context),
533 name_resolver_(context->GetNameResolver()) {
534 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
535 context->GetFieldGeneratorInfo(descriptor),
536 name_resolver_, &variables_, context);
537 }
538
539 RepeatedImmutablePrimitiveFieldLiteGenerator::
~RepeatedImmutablePrimitiveFieldLiteGenerator()540 ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
541
GetNumBitsForMessage() const542 int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
543 return 0;
544 }
545
GenerateInterfaceMembers(io::Printer * printer) const546 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
547 io::Printer* printer) const {
548 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER,
549 context_->options());
550 printer->Print(variables_,
551 "$deprecation$java.util.List<$boxed_type$> "
552 "${$get$capitalized_name$List$}$();\n");
553 printer->Annotate("{", "}", descriptor_);
554 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
555 context_->options());
556 printer->Print(variables_,
557 "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
558 printer->Annotate("{", "}", descriptor_);
559 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER,
560 context_->options());
561 printer->Print(
562 variables_,
563 "$deprecation$$type$ ${$get$capitalized_name$$}$(int index);\n");
564 printer->Annotate("{", "}", descriptor_);
565 }
566
GenerateMembers(io::Printer * printer) const567 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
568 io::Printer* printer) const {
569 printer->Print(variables_, "private $field_list_type$ $name$_;\n");
570 PrintExtraFieldInfo(variables_, printer);
571 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER,
572 context_->options());
573 printer->Print(variables_,
574 "@java.lang.Override\n"
575 "$deprecation$public java.util.List<$boxed_type$>\n"
576 " ${$get$capitalized_name$List$}$() {\n"
577 " return $name$_;\n" // note: unmodifiable list
578 "}\n");
579 printer->Annotate("{", "}", descriptor_);
580 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
581 context_->options());
582 printer->Print(
583 variables_,
584 "@java.lang.Override\n"
585 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
586 " return $name$_.size();\n"
587 "}\n");
588 printer->Annotate("{", "}", descriptor_);
589 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER,
590 context_->options());
591 printer->Print(
592 variables_,
593 "@java.lang.Override\n"
594 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
595 " return $repeated_get$(index);\n"
596 "}\n");
597 printer->Annotate("{", "}", descriptor_);
598
599 if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
600 context_->HasGeneratedMethods(descriptor_->containing_type())) {
601 printer->Print(variables_,
602 "private int $name$MemoizedSerializedSize = -1;\n");
603 }
604
605 printer->Print(
606 variables_,
607 "private void ensure$capitalized_name$IsMutable() {\n"
608 // Use a temporary to avoid a redundant iget-object.
609 " $field_list_type$ tmp = $name$_;\n"
610 " if (!tmp.isModifiable()) {\n"
611 " $name$_ =\n"
612 " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
613 " }\n"
614 "}\n");
615
616 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
617 context_->options());
618 printer->Print(variables_,
619 "private void set$capitalized_name$(\n"
620 " int index, $type$ value) {\n"
621 "$null_check$"
622 " ensure$capitalized_name$IsMutable();\n"
623 " $repeated_set$(index, value);\n"
624 "}\n");
625 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
626 context_->options());
627 printer->Print(variables_,
628 "private void add$capitalized_name$($type$ value) {\n"
629 "$null_check$"
630 " ensure$capitalized_name$IsMutable();\n"
631 " $repeated_add$(value);\n"
632 "}\n");
633 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
634 context_->options());
635 printer->Print(variables_,
636 "private void addAll$capitalized_name$(\n"
637 " java.lang.Iterable<? extends $boxed_type$> values) {\n"
638 " ensure$capitalized_name$IsMutable();\n"
639 " com.google.protobuf.AbstractMessageLite.addAll(\n"
640 " values, $name$_);\n"
641 "}\n");
642 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
643 context_->options());
644 printer->Print(variables_,
645 "private void clear$capitalized_name$() {\n"
646 " $name$_ = $empty_list$;\n"
647 "}\n");
648 }
649
GenerateBuilderMembers(io::Printer * printer) const650 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
651 io::Printer* printer) const {
652 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER,
653 context_->options());
654 printer->Print(variables_,
655 "@java.lang.Override\n"
656 "$deprecation$public java.util.List<$boxed_type$>\n"
657 " ${$get$capitalized_name$List$}$() {\n"
658 " return java.util.Collections.unmodifiableList(\n"
659 " instance.get$capitalized_name$List());\n"
660 "}\n");
661 printer->Annotate("{", "}", descriptor_);
662 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
663 context_->options());
664 printer->Print(
665 variables_,
666 "@java.lang.Override\n"
667 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
668 " return instance.get$capitalized_name$Count();\n"
669 "}\n");
670 printer->Annotate("{", "}", descriptor_);
671 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER,
672 context_->options());
673 printer->Print(
674 variables_,
675 "@java.lang.Override\n"
676 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
677 " return instance.get$capitalized_name$(index);\n"
678 "}\n");
679 printer->Annotate("{", "}", descriptor_);
680 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
681 context_->options(),
682 /* builder */ true);
683 printer->Print(variables_,
684 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
685 " int index, $type$ value) {\n"
686 " copyOnWrite();\n"
687 " instance.set$capitalized_name$(index, value);\n"
688 " return this;\n"
689 "}\n");
690 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
691 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
692 context_->options(),
693 /* builder */ true);
694 printer->Print(variables_,
695 "$deprecation$public Builder "
696 "${$add$capitalized_name$$}$($type$ value) {\n"
697 " copyOnWrite();\n"
698 " instance.add$capitalized_name$(value);\n"
699 " return this;\n"
700 "}\n");
701 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
702 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
703 context_->options(),
704 /* builder */ true);
705 printer->Print(variables_,
706 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
707 " java.lang.Iterable<? extends $boxed_type$> values) {\n"
708 " copyOnWrite();\n"
709 " instance.addAll$capitalized_name$(values);\n"
710 " return this;\n"
711 "}\n");
712 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
713 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
714 context_->options(),
715 /* builder */ true);
716 printer->Print(
717 variables_,
718 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
719 " copyOnWrite();\n"
720 " instance.clear$capitalized_name$();\n"
721 " return this;\n"
722 "}\n");
723 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
724 }
725
GenerateKotlinDslMembers(io::Printer * printer) const726 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
727 io::Printer* printer) const {
728 auto vars = printer->WithVars(variables_);
729 JvmNameContext name_ctx = {context_->options(), printer};
730 printer->Print(
731 "/**\n"
732 " * An uninstantiable, behaviorless type to represent the field in\n"
733 " * generics.\n"
734 " */\n"
735 "@kotlin.OptIn"
736 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
737 "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
738 " : com.google.protobuf.kotlin.DslProxy()\n");
739
740 WriteFieldDocComment(printer, descriptor_, context_->options());
741 printer->Print(
742 "$kt_deprecation$ public val $kt_name$: "
743 "com.google.protobuf.kotlin.DslList"
744 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
745 "$ jvm_synthetic$"
746 " get() = com.google.protobuf.kotlin.DslList(\n"
747 " $kt_dsl_builder$.${$$kt_property_name$List$}$\n"
748 " )\n");
749
750 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
751 context_->options(),
752 /* builder */ false, /* kdoc */ true);
753 printer->Emit(
754 {
755 {"jvm_name", [&] { JvmName("add$kt_capitalized_name$", name_ctx); }},
756 },
757 "$jvm_synthetic$"
758 "$jvm_name$"
759 "public fun com.google.protobuf.kotlin.DslList"
760 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
761 "add(value: $kt_type$) {\n"
762 " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
763 "}");
764
765 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
766 context_->options(),
767 /* builder */ false, /* kdoc */ true);
768 printer->Emit(
769 {
770 {"jvm_name",
771 [&] { JvmName("plusAssign$kt_capitalized_name$", name_ctx); }},
772 },
773 "$jvm_synthetic$"
774 "$jvm_name$"
775 "@Suppress(\"NOTHING_TO_INLINE\")\n"
776 "public inline operator fun com.google.protobuf.kotlin.DslList"
777 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
778 "plusAssign(value: $kt_type$) {\n"
779 " add(value)\n"
780 "}");
781
782 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
783 context_->options(),
784 /* builder */ false, /* kdoc */ true);
785 printer->Emit(
786 {
787 {"jvm_name",
788 [&] { JvmName("addAll$kt_capitalized_name$", name_ctx); }},
789 },
790 "$jvm_synthetic$"
791 "$jvm_name$"
792 "public fun com.google.protobuf.kotlin.DslList"
793 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
794 "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
795 " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
796 "}");
797
798 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
799 context_->options(),
800 /* builder */ false, /* kdoc */ true);
801 printer->Emit(
802 {
803 {"jvm_name",
804 [&] { JvmName("plusAssignAll$kt_capitalized_name$", name_ctx); }},
805 },
806 "$jvm_synthetic$"
807 "$jvm_name$"
808 "@Suppress(\"NOTHING_TO_INLINE\")\n"
809 "public inline operator fun com.google.protobuf.kotlin.DslList"
810 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
811 "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
812 " addAll(values)\n"
813 "}");
814
815 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
816 context_->options(),
817 /* builder */ false, /* kdoc */ true);
818 printer->Emit(
819 {
820 {"jvm_name", [&] { JvmName("set$kt_capitalized_name$", name_ctx); }},
821 },
822 "$jvm_synthetic$"
823 "$jvm_name$"
824 "public operator fun com.google.protobuf.kotlin.DslList"
825 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
826 "set(index: kotlin.Int, value: $kt_type$) {\n"
827 " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
828 "}");
829
830 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
831 context_->options(),
832 /* builder */ false, /* kdoc */ true);
833 printer->Emit(
834 {
835 {"jvm_name",
836 [&] { JvmName("clear$kt_capitalized_name$", name_ctx); }},
837 },
838 "$jvm_synthetic$"
839 "$jvm_name$"
840 "public fun com.google.protobuf.kotlin.DslList"
841 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
842 "clear() {\n"
843 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
844 "}");
845 }
846
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const847 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
848 io::Printer* printer, std::vector<uint16_t>* output) const {
849 WriteIntToUtf16CharSequence(descriptor_->number(), output);
850 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
851 output);
852 printer->Print(variables_, "\"$name$_\",\n");
853 }
854
GenerateInitializationCode(io::Printer * printer) const855 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
856 io::Printer* printer) const {
857 printer->Print(variables_, "$name$_ = $empty_list$;\n");
858 }
859
GetBoxedType() const860 std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
861 return std::string(BoxedPrimitiveTypeName(GetJavaType(descriptor_)));
862 }
863
864 } // namespace java
865 } // namespace compiler
866 } // namespace protobuf
867 } // namespace google
868