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