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
52 namespace google {
53 namespace protobuf {
54 namespace compiler {
55 namespace java {
56
57 namespace {
58
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)59 void 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->message_type());
67 (*variables)["kt_type"] = (*variables)["type"];
68 (*variables)["mutable_type"] =
69 name_resolver->GetMutableClassName(descriptor->message_type());
70 (*variables)["group_or_message"] =
71 (GetType(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(messageBitIndex);
87
88 // Note that these have a trailing ";".
89 (*variables)["set_has_field_bit_message"] =
90 GenerateSetBit(messageBitIndex) + ";";
91 (*variables)["clear_has_field_bit_message"] =
92 GenerateClearBit(messageBitIndex) + ";";
93
94 (*variables)["is_field_present_message"] = GenerateGetBit(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(builderBitIndex);
105 (*variables)["set_has_field_bit_to_local"] =
106 GenerateSetBitToLocal(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
ImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)117 ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator(
118 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
119 : descriptor_(descriptor),
120 messageBitIndex_(messageBitIndex),
121 name_resolver_(context->GetNameResolver()) {
122 SetMessageVariables(descriptor, messageBitIndex, 0,
123 context->GetFieldGeneratorInfo(descriptor),
124 name_resolver_, &variables_);
125 }
126
~ImmutableMessageFieldLiteGenerator()127 ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
128
GetNumBitsForMessage() const129 int 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_) ? 1 : 0;
135 }
136
GenerateInterfaceMembers(io::Printer * printer) const137 void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
138 io::Printer* printer) const {
139 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
140 printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
141 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
142 printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
143 }
144
GenerateMembers(io::Printer * printer) const145 void ImmutableMessageFieldLiteGenerator::GenerateMembers(
146 io::Printer* printer) const {
147
148 printer->Print(variables_, "private $type$ $name$_;\n");
149 PrintExtraFieldInfo(variables_, printer);
150
151 if (HasHasbit(descriptor_)) {
152 WriteFieldDocComment(printer, descriptor_);
153 printer->Print(
154 variables_,
155 "@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("{", "}", descriptor_);
160 WriteFieldDocComment(printer, descriptor_);
161 printer->Print(
162 variables_,
163 "@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("{", "}", descriptor_);
168 } else {
169 WriteFieldDocComment(printer, descriptor_);
170 printer->Print(
171 variables_,
172 "@java.lang.Override\n"
173 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
174 " return $name$_ != null;\n"
175 "}\n");
176 printer->Annotate("{", "}", descriptor_);
177 WriteFieldDocComment(printer, descriptor_);
178 printer->Print(
179 variables_,
180 "@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("{", "}", descriptor_);
185 }
186
187 // Field.Builder setField(Field value)
188 WriteFieldDocComment(printer, descriptor_);
189 printer->Print(variables_,
190 "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, descriptor_);
198 printer->Print(
199 variables_,
200 "@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, descriptor_);
215 printer->Print(variables_,
216 "private void clear$capitalized_name$() {"
217 " $name$_ = null;\n"
218 " $clear_has_field_bit_message$\n"
219 "}\n");
220 }
221
GenerateBuilderMembers(io::Printer * printer) const222 void 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, descriptor_);
229 printer->Print(variables_,
230 "@java.lang.Override\n"
231 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
232 " return instance.has$capitalized_name$();\n"
233 "}\n");
234 printer->Annotate("{", "}", descriptor_);
235
236 // Field getField()
237 WriteFieldDocComment(printer, descriptor_);
238 printer->Print(variables_,
239 "@java.lang.Override\n"
240 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
241 " return instance.get$capitalized_name$();\n"
242 "}\n");
243 printer->Annotate("{", "}", descriptor_);
244
245 // Field.Builder setField(Field value)
246 WriteFieldDocComment(printer, descriptor_);
247 printer->Print(variables_,
248 "$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("{", "}", descriptor_);
255
256 // Field.Builder setField(Field.Builder builderForValue)
257 WriteFieldDocComment(printer, descriptor_);
258 printer->Print(variables_,
259 "$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("{", "}", descriptor_);
266
267 // Field.Builder mergeField(Field value)
268 WriteFieldDocComment(printer, descriptor_);
269 printer->Print(variables_,
270 "$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("{", "}", descriptor_);
277
278 // Field.Builder clearField()
279 WriteFieldDocComment(printer, descriptor_);
280 printer->Print(variables_,
281 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {"
282 " copyOnWrite();\n"
283 " instance.clear$capitalized_name$();\n"
284 " return this;\n"
285 "}\n");
286 printer->Annotate("{", "}", descriptor_);
287 }
288
GenerateKotlinDslMembers(io::Printer * printer) const289 void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
290 io::Printer* printer) const {
291 WriteFieldDocComment(printer, descriptor_);
292 printer->Print(variables_,
293 "$kt_deprecation$public 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, descriptor_, CLEARER,
302 /* builder */ false);
303 printer->Print(variables_,
304 "public fun ${$clear$kt_capitalized_name$$}$() {\n"
305 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
306 "}\n");
307
308 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
309 printer->Print(
310 variables_,
311 "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
312 " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
313 "}\n");
314 GenerateKotlinOrNull(printer);
315 }
316
GenerateKotlinOrNull(io::Printer * printer) const317 void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
318 if (descriptor_->has_optional_keyword()) {
319 printer->Print(variables_,
320 "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n"
321 " get() = $kt_dsl_builder$.$name$OrNull\n");
322 }
323 }
324
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const325 void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
326 io::Printer* printer, std::vector<uint16_t>* output) const {
327 WriteIntToUtf16CharSequence(descriptor_->number(), output);
328 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
329 output);
330 if (HasHasbit(descriptor_)) {
331 WriteIntToUtf16CharSequence(messageBitIndex_, output);
332 }
333 printer->Print(variables_, "\"$name$_\",\n");
334 }
335
GenerateInitializationCode(io::Printer * printer) const336 void ImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
337 io::Printer* printer) const {}
338
GetBoxedType() const339 std::string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
340 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
341 }
342
343 // ===================================================================
344
345 ImmutableMessageOneofFieldLiteGenerator::
ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)346 ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
347 int messageBitIndex,
348 Context* context)
349 : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) {
350 const OneofGeneratorInfo* info =
351 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
352 SetCommonOneofVariables(descriptor, info, &variables_);
353 }
354
355 ImmutableMessageOneofFieldLiteGenerator::
~ImmutableMessageOneofFieldLiteGenerator()356 ~ImmutableMessageOneofFieldLiteGenerator() {}
357
GenerateMembers(io::Printer * printer) const358 void ImmutableMessageOneofFieldLiteGenerator::GenerateMembers(
359 io::Printer* printer) const {
360 PrintExtraFieldInfo(variables_, printer);
361 WriteFieldDocComment(printer, descriptor_);
362 printer->Print(variables_,
363 "@java.lang.Override\n"
364 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
365 " return $has_oneof_case_message$;\n"
366 "}\n");
367 printer->Annotate("{", "}", descriptor_);
368 WriteFieldDocComment(printer, descriptor_);
369 printer->Print(variables_,
370 "@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("{", "}", descriptor_);
378
379 // Field.Builder setField(Field value)
380 WriteFieldDocComment(printer, descriptor_);
381 printer->Print(variables_,
382 "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, descriptor_);
390 printer->Print(
391 variables_,
392 "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, descriptor_);
406 printer->Print(variables_,
407 "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
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const415 void ImmutableMessageOneofFieldLiteGenerator::GenerateFieldInfo(
416 io::Printer* printer, std::vector<uint16_t>* output) const {
417 WriteIntToUtf16CharSequence(descriptor_->number(), output);
418 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
419 output);
420 WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
421 printer->Print(variables_, "$oneof_stored_type$.class,\n");
422 }
423
GenerateBuilderMembers(io::Printer * printer) const424 void 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, descriptor_);
431 printer->Print(variables_,
432 "@java.lang.Override\n"
433 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
434 " return instance.has$capitalized_name$();\n"
435 "}\n");
436 printer->Annotate("{", "}", descriptor_);
437
438 // Field getField()
439 WriteFieldDocComment(printer, descriptor_);
440 printer->Print(variables_,
441 "@java.lang.Override\n"
442 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
443 " return instance.get$capitalized_name$();\n"
444 "}\n");
445 printer->Annotate("{", "}", descriptor_);
446
447 // Field.Builder setField(Field value)
448 WriteFieldDocComment(printer, descriptor_);
449 printer->Print(variables_,
450 "$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("{", "}", descriptor_);
457
458 // Field.Builder setField(Field.Builder builderForValue)
459 WriteFieldDocComment(printer, descriptor_);
460 printer->Print(variables_,
461 "$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("{", "}", descriptor_);
468
469 // Field.Builder mergeField(Field value)
470 WriteFieldDocComment(printer, descriptor_);
471 printer->Print(variables_,
472 "$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("{", "}", descriptor_);
479
480 // Field.Builder clearField()
481 WriteFieldDocComment(printer, descriptor_);
482 printer->Print(
483 variables_,
484 "$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("{", "}", descriptor_);
490 }
491
492 // ===================================================================
493
494 RepeatedImmutableMessageFieldLiteGenerator::
RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)495 RepeatedImmutableMessageFieldLiteGenerator(
496 const FieldDescriptor* descriptor, int messageBitIndex,
497 Context* context)
498 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
499 SetMessageVariables(descriptor, messageBitIndex, 0,
500 context->GetFieldGeneratorInfo(descriptor),
501 name_resolver_, &variables_);
502 }
503
504 RepeatedImmutableMessageFieldLiteGenerator::
~RepeatedImmutableMessageFieldLiteGenerator()505 ~RepeatedImmutableMessageFieldLiteGenerator() {}
506
GetNumBitsForMessage() const507 int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
508 return 0;
509 }
510
GenerateInterfaceMembers(io::Printer * printer) const511 void 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, descriptor_);
518 printer->Print(variables_,
519 "$deprecation$java.util.List<$type$> \n"
520 " get$capitalized_name$List();\n");
521 WriteFieldDocComment(printer, descriptor_);
522 printer->Print(variables_,
523 "$deprecation$$type$ get$capitalized_name$(int index);\n");
524 WriteFieldDocComment(printer, descriptor_);
525 printer->Print(variables_,
526 "$deprecation$int get$capitalized_name$Count();\n");
527 }
528
GenerateMembers(io::Printer * printer) const529 void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers(
530 io::Printer* printer) const {
531 printer->Print(
532 variables_,
533 "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n");
534 PrintExtraFieldInfo(variables_, printer);
535 WriteFieldDocComment(printer, descriptor_);
536 printer->Print(variables_,
537 "@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("{", "}", descriptor_);
543 WriteFieldDocComment(printer, descriptor_);
544 printer->Print(
545 variables_,
546 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
547 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
548 " return $name$_;\n"
549 "}\n");
550 printer->Annotate("{", "}", descriptor_);
551 WriteFieldDocComment(printer, descriptor_);
552 printer->Print(
553 variables_,
554 "@java.lang.Override\n"
555 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
556 " return $name$_.size();\n"
557 "}\n");
558 printer->Annotate("{", "}", descriptor_);
559 WriteFieldDocComment(printer, descriptor_);
560 printer->Print(
561 variables_,
562 "@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("{", "}", descriptor_);
567 WriteFieldDocComment(printer, descriptor_);
568 printer->Print(variables_,
569 "$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("{", "}", descriptor_);
575
576 printer->Print(
577 variables_,
578 "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, descriptor_);
590 printer->Print(variables_,
591 "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, descriptor_);
600 printer->Print(variables_,
601 "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, descriptor_);
609 printer->Print(variables_,
610 "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, descriptor_);
619 printer->Print(variables_,
620 "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, descriptor_);
629 printer->Print(variables_,
630 "private void clear$capitalized_name$() {\n"
631 " $name$_ = emptyProtobufList();\n"
632 "}\n");
633
634 // Builder removeRepeatedField(int index)
635 WriteFieldDocComment(printer, descriptor_);
636 printer->Print(variables_,
637 "private void remove$capitalized_name$(int index) {\n"
638 " ensure$capitalized_name$IsMutable();\n"
639 " $name$_.remove(index);\n"
640 "}\n");
641 }
642
GenerateBuilderMembers(io::Printer * printer) const643 void 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, descriptor_);
650 printer->Print(variables_,
651 "@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("{", "}", descriptor_);
658
659 // int getRepeatedFieldCount()
660 WriteFieldDocComment(printer, descriptor_);
661 printer->Print(
662 variables_,
663 "@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("{", "}", descriptor_);
668
669 // Field getRepeatedField(int index)
670 WriteFieldDocComment(printer, descriptor_);
671 printer->Print(
672 variables_,
673 "@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("{", "}", descriptor_);
678
679 // Builder setRepeatedField(int index, Field value)
680 WriteFieldDocComment(printer, descriptor_);
681 printer->Print(variables_,
682 "$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("{", "}", descriptor_);
689
690 // Builder setRepeatedField(int index, Field.Builder builderForValue)
691 WriteFieldDocComment(printer, descriptor_);
692 printer->Print(variables_,
693 "$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("{", "}", descriptor_);
701
702 // Builder addRepeatedField(Field value)
703 WriteFieldDocComment(printer, descriptor_);
704 printer->Print(variables_,
705 "$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("{", "}", descriptor_);
712
713 // Builder addRepeatedField(int index, Field value)
714 WriteFieldDocComment(printer, descriptor_);
715 printer->Print(variables_,
716 "$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("{", "}", descriptor_);
723 // Builder addRepeatedField(Field.Builder builderForValue)
724 WriteFieldDocComment(printer, descriptor_);
725 printer->Print(variables_,
726 "$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("{", "}", descriptor_);
733
734 // Builder addRepeatedField(int index, Field.Builder builderForValue)
735 WriteFieldDocComment(printer, descriptor_);
736 printer->Print(variables_,
737 "$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("{", "}", descriptor_);
745
746 // Builder addAllRepeatedField(Iterable<Field> values)
747 WriteFieldDocComment(printer, descriptor_);
748 printer->Print(variables_,
749 "$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("{", "}", descriptor_);
756
757 // Builder clearAllRepeatedField()
758 WriteFieldDocComment(printer, descriptor_);
759 printer->Print(
760 variables_,
761 "$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("{", "}", descriptor_);
767
768 // Builder removeRepeatedField(int index)
769 WriteFieldDocComment(printer, descriptor_);
770 printer->Print(variables_,
771 "$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("{", "}", descriptor_);
778 }
779
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const780 void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
781 io::Printer* printer, std::vector<uint16_t>* output) const {
782 WriteIntToUtf16CharSequence(descriptor_->number(), output);
783 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
784 output);
785 printer->Print(variables_,
786 "\"$name$_\",\n"
787 "$type$.class,\n");
788 }
789
GenerateInitializationCode(io::Printer * printer) const790 void RepeatedImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
791 io::Printer* printer) const {
792 printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
793 }
794
GetBoxedType() const795 std::string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const {
796 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
797 }
798
GenerateKotlinDslMembers(io::Printer * printer) const799 void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
800 io::Printer* printer) const {
801 printer->Print(
802 variables_,
803 "/**\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 "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
810 " : com.google.protobuf.kotlin.DslProxy()\n");
811
812 WriteFieldDocComment(printer, descriptor_);
813 printer->Print(variables_,
814 "$kt_deprecation$ public 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, descriptor_, LIST_ADDER,
823 /* builder */ false);
824 printer->Print(variables_,
825 "@kotlin.jvm.JvmSynthetic\n"
826 "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
827 "public 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, descriptor_, LIST_ADDER,
834 /* builder */ false);
835 printer->Print(variables_,
836 "@kotlin.jvm.JvmSynthetic\n"
837 "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
838 "@Suppress(\"NOTHING_TO_INLINE\")\n"
839 "public 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, descriptor_, LIST_MULTI_ADDER,
846 /* builder */ false);
847 printer->Print(variables_,
848 "@kotlin.jvm.JvmSynthetic\n"
849 "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
850 "public 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, descriptor_, LIST_MULTI_ADDER,
857 /* builder */ false);
858 printer->Print(
859 variables_,
860 "@kotlin.jvm.JvmSynthetic\n"
861 "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
862 "@Suppress(\"NOTHING_TO_INLINE\")\n"
863 "public 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, descriptor_, LIST_INDEXED_SETTER,
870 /* builder */ false);
871 printer->Print(
872 variables_,
873 "@kotlin.jvm.JvmSynthetic\n"
874 "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
875 "public 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, descriptor_, CLEARER,
882 /* builder */ false);
883 printer->Print(variables_,
884 "@kotlin.jvm.JvmSynthetic\n"
885 "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
886 "public 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