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/message_field_lite.h>
36
37#include <cstdint>
38#include <map>
39#include <string>
40
41#include <google/protobuf/io/printer.h>
42#include <google/protobuf/wire_format.h>
43#include <google/protobuf/stubs/strutil.h>
44#include <google/protobuf/compiler/java/context.h>
45#include <google/protobuf/compiler/java/doc_comment.h>
46#include <google/protobuf/compiler/java/helpers.h>
47#include <google/protobuf/compiler/java/name_resolver.h>
48
49// Must be last.
50#include <google/protobuf/port_def.inc>
51
52namespace google {
53namespace protobuf {
54namespace compiler {
55namespace java {
56
57namespace {
58
59void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
60 int builderBitIndex, const FieldGeneratorInfo* info,
61 ClassNameResolver* name_resolver,
62 std::map<std::string, std::string>* variables) {
63 SetCommonFieldVariables(descriptor, info, variables);
64
65 (*variables)["type"] =
66 name_resolver->GetImmutableClassName(descriptor: descriptor->message_type());
67 (*variables)["kt_type"] = (*variables)["type"];
68 (*variables)["mutable_type"] =
69 name_resolver->GetMutableClassName(descriptor: descriptor->message_type());
70 (*variables)["group_or_message"] =
71 (GetType(field: descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
72 : "Message";
73 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
74 // by the proto compiler
75 (*variables)["deprecation"] =
76 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
77 (*variables)["kt_deprecation"] =
78 descriptor->options().deprecated()
79 ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
80 " is deprecated\") "
81 : "";
82 (*variables)["required"] = descriptor->is_required() ? "true" : "false";
83
84 if (HasHasbit(descriptor)) {
85 // For singular messages and builders, one bit is used for the hasField bit.
86 (*variables)["get_has_field_bit_message"] = GenerateGetBit(bitIndex: messageBitIndex);
87
88 // Note that these have a trailing ";".
89 (*variables)["set_has_field_bit_message"] =
90 GenerateSetBit(bitIndex: messageBitIndex) + ";";
91 (*variables)["clear_has_field_bit_message"] =
92 GenerateClearBit(bitIndex: messageBitIndex) + ";";
93
94 (*variables)["is_field_present_message"] = GenerateGetBit(bitIndex: messageBitIndex);
95 } else {
96 (*variables)["set_has_field_bit_message"] = "";
97 (*variables)["clear_has_field_bit_message"] = "";
98
99 (*variables)["is_field_present_message"] =
100 (*variables)["name"] + "_ != null";
101 }
102
103 (*variables)["get_has_field_bit_from_local"] =
104 GenerateGetBitFromLocal(bitIndex: builderBitIndex);
105 (*variables)["set_has_field_bit_to_local"] =
106 GenerateSetBitToLocal(bitIndex: messageBitIndex);
107
108 // We use `x.getClass()` as a null check because it generates less bytecode
109 // than an `if (x == null) { throw ... }` statement.
110 (*variables)["null_check"] = "value.getClass();\n";
111}
112
113} // namespace
114
115// ===================================================================
116
117ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator(
118 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
119 : descriptor_(descriptor),
120 messageBitIndex_(messageBitIndex),
121 name_resolver_(context->GetNameResolver()) {
122 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex: 0,
123 info: context->GetFieldGeneratorInfo(field: descriptor),
124 name_resolver: name_resolver_, variables: &variables_);
125}
126
127ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
128
129int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
130 // TODO(dweis): We don't need a has bit for messages as they have null
131 // sentinels and no user should be reflecting on this. We could save some
132 // bits by setting to 0 and updating the runtimes but this might come at a
133 // runtime performance cost since we can't memoize has-bit reads.
134 return HasHasbit(descriptor: descriptor_) ? 1 : 0;
135}
136
137void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
138 io::Printer* printer) const {
139 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
140 printer->Print(variables: variables_, text: "$deprecation$boolean has$capitalized_name$();\n");
141 WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER);
142 printer->Print(variables: variables_, text: "$deprecation$$type$ get$capitalized_name$();\n");
143}
144
145void ImmutableMessageFieldLiteGenerator::GenerateMembers(
146 io::Printer* printer) const {
147
148 printer->Print(variables: variables_, text: "private $type$ $name$_;\n");
149 PrintExtraFieldInfo(variables: variables_, printer);
150
151 if (HasHasbit(descriptor: descriptor_)) {
152 WriteFieldDocComment(printer, field: descriptor_);
153 printer->Print(
154 variables: variables_,
155 text: "@java.lang.Override\n"
156 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
157 " return $get_has_field_bit_message$;\n"
158 "}\n");
159 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
160 WriteFieldDocComment(printer, field: descriptor_);
161 printer->Print(
162 variables: variables_,
163 text: "@java.lang.Override\n"
164 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
165 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
166 "}\n");
167 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
168 } else {
169 WriteFieldDocComment(printer, field: descriptor_);
170 printer->Print(
171 variables: variables_,
172 text: "@java.lang.Override\n"
173 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
174 " return $name$_ != null;\n"
175 "}\n");
176 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
177 WriteFieldDocComment(printer, field: descriptor_);
178 printer->Print(
179 variables: variables_,
180 text: "@java.lang.Override\n"
181 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
182 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
183 "}\n");
184 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
185 }
186
187 // Field.Builder setField(Field value)
188 WriteFieldDocComment(printer, field: descriptor_);
189 printer->Print(variables: variables_,
190 text: "private void set$capitalized_name$($type$ value) {\n"
191 " $null_check$"
192 " $name$_ = value;\n"
193 " $set_has_field_bit_message$\n"
194 " }\n");
195
196 // Field.Builder mergeField(Field value)
197 WriteFieldDocComment(printer, field: descriptor_);
198 printer->Print(
199 variables: variables_,
200 text: "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n"
201 "private void merge$capitalized_name$($type$ value) {\n"
202 " $null_check$"
203 " if ($name$_ != null &&\n"
204 " $name$_ != $type$.getDefaultInstance()) {\n"
205 " $name$_ =\n"
206 " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
207 " } else {\n"
208 " $name$_ = value;\n"
209 " }\n"
210 " $set_has_field_bit_message$\n"
211 "}\n");
212
213 // Field.Builder clearField()
214 WriteFieldDocComment(printer, field: descriptor_);
215 printer->Print(variables: variables_,
216 text: "private void clear$capitalized_name$() {"
217 " $name$_ = null;\n"
218 " $clear_has_field_bit_message$\n"
219 "}\n");
220}
221
222void ImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
223 io::Printer* printer) const {
224 // The comments above the methods below are based on a hypothetical
225 // field of type "Field" called "Field".
226
227 // boolean hasField()
228 WriteFieldDocComment(printer, field: descriptor_);
229 printer->Print(variables: variables_,
230 text: "@java.lang.Override\n"
231 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
232 " return instance.has$capitalized_name$();\n"
233 "}\n");
234 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
235
236 // Field getField()
237 WriteFieldDocComment(printer, field: descriptor_);
238 printer->Print(variables: variables_,
239 text: "@java.lang.Override\n"
240 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
241 " return instance.get$capitalized_name$();\n"
242 "}\n");
243 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
244
245 // Field.Builder setField(Field value)
246 WriteFieldDocComment(printer, field: descriptor_);
247 printer->Print(variables: variables_,
248 text: "$deprecation$public Builder "
249 "${$set$capitalized_name$$}$($type$ value) {\n"
250 " copyOnWrite();\n"
251 " instance.set$capitalized_name$(value);\n"
252 " return this;\n"
253 " }\n");
254 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
255
256 // Field.Builder setField(Field.Builder builderForValue)
257 WriteFieldDocComment(printer, field: descriptor_);
258 printer->Print(variables: variables_,
259 text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
260 " $type$.Builder builderForValue) {\n"
261 " copyOnWrite();\n"
262 " instance.set$capitalized_name$(builderForValue.build());\n"
263 " return this;\n"
264 "}\n");
265 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
266
267 // Field.Builder mergeField(Field value)
268 WriteFieldDocComment(printer, field: descriptor_);
269 printer->Print(variables: variables_,
270 text: "$deprecation$public Builder "
271 "${$merge$capitalized_name$$}$($type$ value) {\n"
272 " copyOnWrite();\n"
273 " instance.merge$capitalized_name$(value);\n"
274 " return this;\n"
275 "}\n");
276 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
277
278 // Field.Builder clearField()
279 WriteFieldDocComment(printer, field: descriptor_);
280 printer->Print(variables: variables_,
281 text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {"
282 " copyOnWrite();\n"
283 " instance.clear$capitalized_name$();\n"
284 " return this;\n"
285 "}\n");
286 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
287}
288
289void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
290 io::Printer* printer) const {
291 WriteFieldDocComment(printer, field: descriptor_);
292 printer->Print(variables: variables_,
293 text: "$kt_deprecation$var $kt_name$: $kt_type$\n"
294 " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
295 " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
296 " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
297 " set(value) {\n"
298 " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
299 " }\n");
300
301 WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER,
302 /* builder */ false);
303 printer->Print(variables: variables_,
304 text: "fun ${$clear$kt_capitalized_name$$}$() {\n"
305 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
306 "}\n");
307
308 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
309 printer->Print(
310 variables: variables_,
311 text: "fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
312 " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
313 "}\n");
314 GenerateKotlinOrNull(printer);
315}
316
317void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
318 if (descriptor_->has_optional_keyword()) {
319 printer->Print(variables: variables_,
320 text: "val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n"
321 " get() = $kt_dsl_builder$.$name$OrNull\n");
322 }
323}
324
325void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
326 io::Printer* printer, std::vector<uint16_t>* output) const {
327 WriteIntToUtf16CharSequence(value: descriptor_->number(), output);
328 WriteIntToUtf16CharSequence(value: GetExperimentalJavaFieldType(field: descriptor_),
329 output);
330 if (HasHasbit(descriptor: descriptor_)) {
331 WriteIntToUtf16CharSequence(value: messageBitIndex_, output);
332 }
333 printer->Print(variables: variables_, text: "\"$name$_\",\n");
334}
335
336void ImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
337 io::Printer* printer) const {}
338
339std::string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
340 return name_resolver_->GetImmutableClassName(descriptor: descriptor_->message_type());
341}
342
343// ===================================================================
344
345ImmutableMessageOneofFieldLiteGenerator::
346 ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
347 int messageBitIndex,
348 Context* context)
349 : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) {
350 const OneofGeneratorInfo* info =
351 context->GetOneofGeneratorInfo(oneof: descriptor->containing_oneof());
352 SetCommonOneofVariables(descriptor, info, variables: &variables_);
353}
354
355ImmutableMessageOneofFieldLiteGenerator::
356 ~ImmutableMessageOneofFieldLiteGenerator() {}
357
358void ImmutableMessageOneofFieldLiteGenerator::GenerateMembers(
359 io::Printer* printer) const {
360 PrintExtraFieldInfo(variables: variables_, printer);
361 WriteFieldDocComment(printer, field: descriptor_);
362 printer->Print(variables: variables_,
363 text: "@java.lang.Override\n"
364 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
365 " return $has_oneof_case_message$;\n"
366 "}\n");
367 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
368 WriteFieldDocComment(printer, field: descriptor_);
369 printer->Print(variables: variables_,
370 text: "@java.lang.Override\n"
371 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
372 " if ($has_oneof_case_message$) {\n"
373 " return ($type$) $oneof_name$_;\n"
374 " }\n"
375 " return $type$.getDefaultInstance();\n"
376 "}\n");
377 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
378
379 // Field.Builder setField(Field value)
380 WriteFieldDocComment(printer, field: descriptor_);
381 printer->Print(variables: variables_,
382 text: "private void set$capitalized_name$($type$ value) {\n"
383 " $null_check$"
384 " $oneof_name$_ = value;\n"
385 " $set_oneof_case_message$;\n"
386 "}\n");
387
388 // Field.Builder mergeField(Field value)
389 WriteFieldDocComment(printer, field: descriptor_);
390 printer->Print(
391 variables: variables_,
392 text: "private void merge$capitalized_name$($type$ value) {\n"
393 " $null_check$"
394 " if ($has_oneof_case_message$ &&\n"
395 " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
396 " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
397 " .mergeFrom(value).buildPartial();\n"
398 " } else {\n"
399 " $oneof_name$_ = value;\n"
400 " }\n"
401 " $set_oneof_case_message$;\n"
402 "}\n");
403
404 // Field.Builder clearField()
405 WriteFieldDocComment(printer, field: descriptor_);
406 printer->Print(variables: variables_,
407 text: "private void clear$capitalized_name$() {\n"
408 " if ($has_oneof_case_message$) {\n"
409 " $clear_oneof_case_message$;\n"
410 " $oneof_name$_ = null;\n"
411 " }\n"
412 "}\n");
413}
414
415void ImmutableMessageOneofFieldLiteGenerator::GenerateFieldInfo(
416 io::Printer* printer, std::vector<uint16_t>* output) const {
417 WriteIntToUtf16CharSequence(value: descriptor_->number(), output);
418 WriteIntToUtf16CharSequence(value: GetExperimentalJavaFieldType(field: descriptor_),
419 output);
420 WriteIntToUtf16CharSequence(value: descriptor_->containing_oneof()->index(), output);
421 printer->Print(variables: variables_, text: "$oneof_stored_type$.class,\n");
422}
423
424void ImmutableMessageOneofFieldLiteGenerator::GenerateBuilderMembers(
425 io::Printer* printer) const {
426 // The comments above the methods below are based on a hypothetical
427 // field of type "Field" called "Field".
428
429 // boolean hasField()
430 WriteFieldDocComment(printer, field: descriptor_);
431 printer->Print(variables: variables_,
432 text: "@java.lang.Override\n"
433 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
434 " return instance.has$capitalized_name$();\n"
435 "}\n");
436 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
437
438 // Field getField()
439 WriteFieldDocComment(printer, field: descriptor_);
440 printer->Print(variables: variables_,
441 text: "@java.lang.Override\n"
442 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
443 " return instance.get$capitalized_name$();\n"
444 "}\n");
445 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
446
447 // Field.Builder setField(Field value)
448 WriteFieldDocComment(printer, field: descriptor_);
449 printer->Print(variables: variables_,
450 text: "$deprecation$public Builder "
451 "${$set$capitalized_name$$}$($type$ value) {\n"
452 " copyOnWrite();\n"
453 " instance.set$capitalized_name$(value);\n"
454 " return this;\n"
455 "}\n");
456 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
457
458 // Field.Builder setField(Field.Builder builderForValue)
459 WriteFieldDocComment(printer, field: descriptor_);
460 printer->Print(variables: variables_,
461 text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
462 " $type$.Builder builderForValue) {\n"
463 " copyOnWrite();\n"
464 " instance.set$capitalized_name$(builderForValue.build());\n"
465 " return this;\n"
466 "}\n");
467 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
468
469 // Field.Builder mergeField(Field value)
470 WriteFieldDocComment(printer, field: descriptor_);
471 printer->Print(variables: variables_,
472 text: "$deprecation$public Builder "
473 "${$merge$capitalized_name$$}$($type$ value) {\n"
474 " copyOnWrite();\n"
475 " instance.merge$capitalized_name$(value);\n"
476 " return this;\n"
477 "}\n");
478 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
479
480 // Field.Builder clearField()
481 WriteFieldDocComment(printer, field: descriptor_);
482 printer->Print(
483 variables: variables_,
484 text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
485 " copyOnWrite();\n"
486 " instance.clear$capitalized_name$();\n"
487 " return this;\n"
488 "}\n");
489 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
490}
491
492// ===================================================================
493
494RepeatedImmutableMessageFieldLiteGenerator::
495 RepeatedImmutableMessageFieldLiteGenerator(
496 const FieldDescriptor* descriptor, int messageBitIndex,
497 Context* context)
498 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
499 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex: 0,
500 info: context->GetFieldGeneratorInfo(field: descriptor),
501 name_resolver: name_resolver_, variables: &variables_);
502}
503
504RepeatedImmutableMessageFieldLiteGenerator::
505 ~RepeatedImmutableMessageFieldLiteGenerator() {}
506
507int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
508 return 0;
509}
510
511void RepeatedImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
512 io::Printer* printer) const {
513 // TODO(jonp): In the future, consider having methods specific to the
514 // interface so that builders can choose dynamically to either return a
515 // message or a nested builder, so that asking for the interface doesn't
516 // cause a message to ever be built.
517 WriteFieldDocComment(printer, field: descriptor_);
518 printer->Print(variables: variables_,
519 text: "$deprecation$java.util.List<$type$> \n"
520 " get$capitalized_name$List();\n");
521 WriteFieldDocComment(printer, field: descriptor_);
522 printer->Print(variables: variables_,
523 text: "$deprecation$$type$ get$capitalized_name$(int index);\n");
524 WriteFieldDocComment(printer, field: descriptor_);
525 printer->Print(variables: variables_,
526 text: "$deprecation$int get$capitalized_name$Count();\n");
527}
528
529void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers(
530 io::Printer* printer) const {
531 printer->Print(
532 variables: variables_,
533 text: "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n");
534 PrintExtraFieldInfo(variables: variables_, printer);
535 WriteFieldDocComment(printer, field: descriptor_);
536 printer->Print(variables: variables_,
537 text: "@java.lang.Override\n"
538 "$deprecation$public java.util.List<$type$> "
539 "${$get$capitalized_name$List$}$() {\n"
540 " return $name$_;\n" // note: unmodifiable list
541 "}\n");
542 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
543 WriteFieldDocComment(printer, field: descriptor_);
544 printer->Print(
545 variables: variables_,
546 text: "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
547 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
548 " return $name$_;\n"
549 "}\n");
550 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
551 WriteFieldDocComment(printer, field: descriptor_);
552 printer->Print(
553 variables: variables_,
554 text: "@java.lang.Override\n"
555 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
556 " return $name$_.size();\n"
557 "}\n");
558 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
559 WriteFieldDocComment(printer, field: descriptor_);
560 printer->Print(
561 variables: variables_,
562 text: "@java.lang.Override\n"
563 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
564 " return $name$_.get(index);\n"
565 "}\n");
566 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
567 WriteFieldDocComment(printer, field: descriptor_);
568 printer->Print(variables: variables_,
569 text: "$deprecation$public $type$OrBuilder "
570 "${$get$capitalized_name$OrBuilder$}$(\n"
571 " int index) {\n"
572 " return $name$_.get(index);\n"
573 "}\n");
574 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
575
576 printer->Print(
577 variables: variables_,
578 text: "private void ensure$capitalized_name$IsMutable() {\n"
579 // Use a temporary to avoid a redundant iget-object.
580 " com.google.protobuf.Internal.ProtobufList<$type$> tmp = $name$_;\n"
581 " if (!tmp.isModifiable()) {\n"
582 " $name$_ =\n"
583 " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
584 " }\n"
585 "}\n"
586 "\n");
587
588 // Builder setRepeatedField(int index, Field value)
589 WriteFieldDocComment(printer, field: descriptor_);
590 printer->Print(variables: variables_,
591 text: "private void set$capitalized_name$(\n"
592 " int index, $type$ value) {\n"
593 " $null_check$"
594 " ensure$capitalized_name$IsMutable();\n"
595 " $name$_.set(index, value);\n"
596 "}\n");
597
598 // Builder addRepeatedField(Field value)
599 WriteFieldDocComment(printer, field: descriptor_);
600 printer->Print(variables: variables_,
601 text: "private void add$capitalized_name$($type$ value) {\n"
602 " $null_check$"
603 " ensure$capitalized_name$IsMutable();\n"
604 " $name$_.add(value);\n"
605 "}\n");
606
607 // Builder addRepeatedField(int index, Field value)
608 WriteFieldDocComment(printer, field: descriptor_);
609 printer->Print(variables: variables_,
610 text: "private void add$capitalized_name$(\n"
611 " int index, $type$ value) {\n"
612 " $null_check$"
613 " ensure$capitalized_name$IsMutable();\n"
614 " $name$_.add(index, value);\n"
615 "}\n");
616
617 // Builder addAllRepeatedField(Iterable<Field> values)
618 WriteFieldDocComment(printer, field: descriptor_);
619 printer->Print(variables: variables_,
620 text: "private void addAll$capitalized_name$(\n"
621 " java.lang.Iterable<? extends $type$> values) {\n"
622 " ensure$capitalized_name$IsMutable();\n"
623 " com.google.protobuf.AbstractMessageLite.addAll(\n"
624 " values, $name$_);\n"
625 "}\n");
626
627 // Builder clearAllRepeatedField()
628 WriteFieldDocComment(printer, field: descriptor_);
629 printer->Print(variables: variables_,
630 text: "private void clear$capitalized_name$() {\n"
631 " $name$_ = emptyProtobufList();\n"
632 "}\n");
633
634 // Builder removeRepeatedField(int index)
635 WriteFieldDocComment(printer, field: descriptor_);
636 printer->Print(variables: variables_,
637 text: "private void remove$capitalized_name$(int index) {\n"
638 " ensure$capitalized_name$IsMutable();\n"
639 " $name$_.remove(index);\n"
640 "}\n");
641}
642
643void RepeatedImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
644 io::Printer* printer) const {
645 // The comments above the methods below are based on a hypothetical
646 // repeated field of type "Field" called "RepeatedField".
647
648 // List<Field> getRepeatedFieldList()
649 WriteFieldDocComment(printer, field: descriptor_);
650 printer->Print(variables: variables_,
651 text: "@java.lang.Override\n"
652 "$deprecation$public java.util.List<$type$> "
653 "${$get$capitalized_name$List$}$() {\n"
654 " return java.util.Collections.unmodifiableList(\n"
655 " instance.get$capitalized_name$List());\n"
656 "}\n");
657 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
658
659 // int getRepeatedFieldCount()
660 WriteFieldDocComment(printer, field: descriptor_);
661 printer->Print(
662 variables: variables_,
663 text: "@java.lang.Override\n"
664 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
665 " return instance.get$capitalized_name$Count();\n"
666 "}");
667 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
668
669 // Field getRepeatedField(int index)
670 WriteFieldDocComment(printer, field: descriptor_);
671 printer->Print(
672 variables: variables_,
673 text: "@java.lang.Override\n"
674 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
675 " return instance.get$capitalized_name$(index);\n"
676 "}\n");
677 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
678
679 // Builder setRepeatedField(int index, Field value)
680 WriteFieldDocComment(printer, field: descriptor_);
681 printer->Print(variables: variables_,
682 text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
683 " int index, $type$ value) {\n"
684 " copyOnWrite();\n"
685 " instance.set$capitalized_name$(index, value);\n"
686 " return this;\n"
687 "}\n");
688 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
689
690 // Builder setRepeatedField(int index, Field.Builder builderForValue)
691 WriteFieldDocComment(printer, field: descriptor_);
692 printer->Print(variables: variables_,
693 text: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
694 " int index, $type$.Builder builderForValue) {\n"
695 " copyOnWrite();\n"
696 " instance.set$capitalized_name$(index,\n"
697 " builderForValue.build());\n"
698 " return this;\n"
699 "}\n");
700 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
701
702 // Builder addRepeatedField(Field value)
703 WriteFieldDocComment(printer, field: descriptor_);
704 printer->Print(variables: variables_,
705 text: "$deprecation$public Builder "
706 "${$add$capitalized_name$$}$($type$ value) {\n"
707 " copyOnWrite();\n"
708 " instance.add$capitalized_name$(value);\n"
709 " return this;\n"
710 "}\n");
711 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
712
713 // Builder addRepeatedField(int index, Field value)
714 WriteFieldDocComment(printer, field: descriptor_);
715 printer->Print(variables: variables_,
716 text: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
717 " int index, $type$ value) {\n"
718 " copyOnWrite();\n"
719 " instance.add$capitalized_name$(index, value);\n"
720 " return this;\n"
721 "}\n");
722 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
723 // Builder addRepeatedField(Field.Builder builderForValue)
724 WriteFieldDocComment(printer, field: descriptor_);
725 printer->Print(variables: variables_,
726 text: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
727 " $type$.Builder builderForValue) {\n"
728 " copyOnWrite();\n"
729 " instance.add$capitalized_name$(builderForValue.build());\n"
730 " return this;\n"
731 "}\n");
732 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
733
734 // Builder addRepeatedField(int index, Field.Builder builderForValue)
735 WriteFieldDocComment(printer, field: descriptor_);
736 printer->Print(variables: variables_,
737 text: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
738 " int index, $type$.Builder builderForValue) {\n"
739 " copyOnWrite();\n"
740 " instance.add$capitalized_name$(index,\n"
741 " builderForValue.build());\n"
742 " return this;\n"
743 "}\n");
744 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
745
746 // Builder addAllRepeatedField(Iterable<Field> values)
747 WriteFieldDocComment(printer, field: descriptor_);
748 printer->Print(variables: variables_,
749 text: "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
750 " java.lang.Iterable<? extends $type$> values) {\n"
751 " copyOnWrite();\n"
752 " instance.addAll$capitalized_name$(values);\n"
753 " return this;\n"
754 "}\n");
755 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
756
757 // Builder clearAllRepeatedField()
758 WriteFieldDocComment(printer, field: descriptor_);
759 printer->Print(
760 variables: variables_,
761 text: "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
762 " copyOnWrite();\n"
763 " instance.clear$capitalized_name$();\n"
764 " return this;\n"
765 "}\n");
766 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
767
768 // Builder removeRepeatedField(int index)
769 WriteFieldDocComment(printer, field: descriptor_);
770 printer->Print(variables: variables_,
771 text: "$deprecation$public Builder "
772 "${$remove$capitalized_name$$}$(int index) {\n"
773 " copyOnWrite();\n"
774 " instance.remove$capitalized_name$(index);\n"
775 " return this;\n"
776 "}\n");
777 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
778}
779
780void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
781 io::Printer* printer, std::vector<uint16_t>* output) const {
782 WriteIntToUtf16CharSequence(value: descriptor_->number(), output);
783 WriteIntToUtf16CharSequence(value: GetExperimentalJavaFieldType(field: descriptor_),
784 output);
785 printer->Print(variables: variables_,
786 text: "\"$name$_\",\n"
787 "$type$.class,\n");
788}
789
790void RepeatedImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
791 io::Printer* printer) const {
792 printer->Print(variables: variables_, text: "$name$_ = emptyProtobufList();\n");
793}
794
795std::string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const {
796 return name_resolver_->GetImmutableClassName(descriptor: descriptor_->message_type());
797}
798
799void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
800 io::Printer* printer) const {
801 printer->Print(
802 variables: variables_,
803 text: "/**\n"
804 " * An uninstantiable, behaviorless type to represent the field in\n"
805 " * generics.\n"
806 " */\n"
807 "@kotlin.OptIn"
808 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
809 "class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
810 " : com.google.protobuf.kotlin.DslProxy()\n");
811
812 WriteFieldDocComment(printer, field: descriptor_);
813 printer->Print(variables: variables_,
814 text: "$kt_deprecation$ val $kt_name$: "
815 "com.google.protobuf.kotlin.DslList"
816 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
817 " @kotlin.jvm.JvmSynthetic\n"
818 " get() = com.google.protobuf.kotlin.DslList(\n"
819 " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
820 " )\n");
821
822 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER,
823 /* builder */ false);
824 printer->Print(variables: variables_,
825 text: "@kotlin.jvm.JvmSynthetic\n"
826 "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
827 "fun com.google.protobuf.kotlin.DslList"
828 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
829 "add(value: $kt_type$) {\n"
830 " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
831 "}\n");
832
833 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER,
834 /* builder */ false);
835 printer->Print(variables: variables_,
836 text: "@kotlin.jvm.JvmSynthetic\n"
837 "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
838 "@Suppress(\"NOTHING_TO_INLINE\")\n"
839 "inline operator fun com.google.protobuf.kotlin.DslList"
840 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
841 "plusAssign(value: $kt_type$) {\n"
842 " add(value)\n"
843 "}\n");
844
845 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER,
846 /* builder */ false);
847 printer->Print(variables: variables_,
848 text: "@kotlin.jvm.JvmSynthetic\n"
849 "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
850 "fun com.google.protobuf.kotlin.DslList"
851 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
852 "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
853 " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
854 "}\n");
855
856 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER,
857 /* builder */ false);
858 printer->Print(
859 variables: variables_,
860 text: "@kotlin.jvm.JvmSynthetic\n"
861 "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
862 "@Suppress(\"NOTHING_TO_INLINE\")\n"
863 "inline operator fun com.google.protobuf.kotlin.DslList"
864 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
865 "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
866 " addAll(values)\n"
867 "}\n");
868
869 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_SETTER,
870 /* builder */ false);
871 printer->Print(
872 variables: variables_,
873 text: "@kotlin.jvm.JvmSynthetic\n"
874 "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
875 "operator fun com.google.protobuf.kotlin.DslList"
876 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
877 "set(index: kotlin.Int, value: $kt_type$) {\n"
878 " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
879 "}\n");
880
881 WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER,
882 /* builder */ false);
883 printer->Print(variables: variables_,
884 text: "@kotlin.jvm.JvmSynthetic\n"
885 "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
886 "fun com.google.protobuf.kotlin.DslList"
887 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
888 "clear() {\n"
889 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
890 "}\n");
891}
892
893} // namespace java
894} // namespace compiler
895} // namespace protobuf
896} // namespace google
897
898#include <google/protobuf/port_undef.inc>
899