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