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 // Author: jonp@google.com (Jon Perlow)
33 // Based on original Protocol Buffers design by
34 // Sanjay Ghemawat, Jeff Dean, and others.
35
36 #include <map>
37 #include <string>
38
39 #include <google/protobuf/stubs/logging.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/compiler/java/java_context.h>
42 #include <google/protobuf/compiler/java/java_doc_comment.h>
43 #include <google/protobuf/compiler/java/java_helpers.h>
44 #include <google/protobuf/compiler/java/java_name_resolver.h>
45 #include <google/protobuf/compiler/java/java_string_field_lite.h>
46 #include <google/protobuf/io/printer.h>
47 #include <google/protobuf/wire_format.h>
48 #include <google/protobuf/stubs/strutil.h>
49
50 namespace google {
51 namespace protobuf {
52 namespace compiler {
53 namespace java {
54
55 using internal::WireFormat;
56 using internal::WireFormatLite;
57
58 namespace {
59
SetPrimitiveVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)60 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
61 int messageBitIndex, int builderBitIndex,
62 const FieldGeneratorInfo* info,
63 ClassNameResolver* name_resolver,
64 std::map<std::string, std::string>* variables) {
65 SetCommonFieldVariables(descriptor, info, variables);
66
67 (*variables)["empty_list"] =
68 "com.google.protobuf.GeneratedMessageLite.emptyProtobufList()";
69
70 (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
71 (*variables)["default_init"] =
72 "= " + ImmutableDefaultValue(descriptor, name_resolver);
73 (*variables)["capitalized_type"] = "java.lang.String";
74 (*variables)["tag"] =
75 StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
76 (*variables)["tag_size"] = StrCat(
77 WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
78 // We use `x.getClass()` as a null check because it generates less bytecode
79 // than an `if (x == null) { throw ... }` statement.
80 (*variables)["null_check"] = " value.getClass();\n";
81
82 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
83 // by the proto compiler
84 (*variables)["deprecation"] =
85 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
86 (*variables)["required"] = descriptor->is_required() ? "true" : "false";
87
88 if (SupportFieldPresence(descriptor)) {
89 // For singular messages and builders, one bit is used for the hasField bit.
90 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
91
92 // Note that these have a trailing ";".
93 (*variables)["set_has_field_bit_message"] =
94 GenerateSetBit(messageBitIndex) + ";";
95 (*variables)["clear_has_field_bit_message"] =
96 GenerateClearBit(messageBitIndex) + ";";
97
98 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
99 } else {
100 (*variables)["set_has_field_bit_message"] = "";
101 (*variables)["clear_has_field_bit_message"] = "";
102
103 (*variables)["is_field_present_message"] =
104 "!" + (*variables)["name"] + "_.isEmpty()";
105 }
106
107 (*variables)["get_has_field_bit_from_local"] =
108 GenerateGetBitFromLocal(builderBitIndex);
109 (*variables)["set_has_field_bit_to_local"] =
110 GenerateSetBitToLocal(messageBitIndex);
111 }
112
113 } // namespace
114
115 // ===================================================================
116
ImmutableStringFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)117 ImmutableStringFieldLiteGenerator::ImmutableStringFieldLiteGenerator(
118 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
119 : descriptor_(descriptor),
120 messageBitIndex_(messageBitIndex),
121 name_resolver_(context->GetNameResolver()) {
122 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
123 context->GetFieldGeneratorInfo(descriptor),
124 name_resolver_, &variables_);
125 }
126
~ImmutableStringFieldLiteGenerator()127 ImmutableStringFieldLiteGenerator::~ImmutableStringFieldLiteGenerator() {}
128
GetNumBitsForMessage() const129 int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const {
130 return SupportFieldPresence(descriptor_) ? 1 : 0;
131 }
132
133 // A note about how strings are handled. In the SPEED and CODE_SIZE runtimes,
134 // strings are not stored as java.lang.String in the Message because of two
135 // issues:
136 //
137 // 1. It wouldn't roundtrip byte arrays that were not valid UTF-8 encoded
138 // strings, but rather fields that were raw bytes incorrectly marked
139 // as strings in the proto file. This is common because in the proto1
140 // syntax, string was the way to indicate bytes and C++ engineers can
141 // easily make this mistake without affecting the C++ API. By converting to
142 // strings immediately, some java code might corrupt these byte arrays as
143 // it passes through a java server even if the field was never accessed by
144 // application code.
145 //
146 // 2. There's a performance hit to converting between bytes and strings and
147 // it many cases, the field is never even read by the application code. This
148 // avoids unnecessary conversions in the common use cases.
149 //
150 // In the LITE_RUNTIME, we store strings as java.lang.String because we assume
151 // that the users of this runtime are not subject to proto1 constraints and are
152 // running code on devices that are user facing. That is, the developers are
153 // properly incentivized to only fetch the data they need to read and wish to
154 // reduce the number of allocations incurred when running on a user's device.
155
156 // TODO(dweis): Consider dropping all of the *Bytes() methods. They really
157 // shouldn't be necessary or used on devices.
GenerateInterfaceMembers(io::Printer * printer) const158 void ImmutableStringFieldLiteGenerator::GenerateInterfaceMembers(
159 io::Printer* printer) const {
160 if (SupportFieldPresence(descriptor_)) {
161 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
162 printer->Print(variables_,
163 "$deprecation$boolean has$capitalized_name$();\n");
164 }
165 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
166 printer->Print(variables_,
167 "$deprecation$java.lang.String get$capitalized_name$();\n");
168 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
169 printer->Print(variables_,
170 "$deprecation$com.google.protobuf.ByteString\n"
171 " get$capitalized_name$Bytes();\n");
172 }
173
GenerateMembers(io::Printer * printer) const174 void ImmutableStringFieldLiteGenerator::GenerateMembers(
175 io::Printer* printer) const {
176 printer->Print(variables_, "private java.lang.String $name$_;\n");
177 PrintExtraFieldInfo(variables_, printer);
178
179 if (SupportFieldPresence(descriptor_)) {
180 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
181 printer->Print(
182 variables_,
183 "@java.lang.Override\n"
184 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
185 " return $get_has_field_bit_message$;\n"
186 "}\n");
187 printer->Annotate("{", "}", descriptor_);
188 }
189
190 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
191 printer->Print(
192 variables_,
193 "@java.lang.Override\n"
194 "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
195 " return $name$_;\n"
196 "}\n");
197 printer->Annotate("{", "}", descriptor_);
198 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
199 printer->Print(
200 variables_,
201 "@java.lang.Override\n"
202 "$deprecation$public com.google.protobuf.ByteString\n"
203 " ${$get$capitalized_name$Bytes$}$() {\n"
204 " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n"
205 "}\n");
206 printer->Annotate("{", "}", descriptor_);
207
208 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
209 printer->Print(variables_,
210 "private void set$capitalized_name$(\n"
211 " java.lang.String value) {\n"
212 "$null_check$"
213 " $set_has_field_bit_message$\n"
214 " $name$_ = value;\n"
215 "}\n");
216 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
217 printer->Print(variables_,
218 "private void clear$capitalized_name$() {\n"
219 " $clear_has_field_bit_message$\n"
220 // The default value is not a simple literal so we want to
221 // avoid executing it multiple times. Instead, get the default
222 // out of the default instance.
223 " $name$_ = getDefaultInstance().get$capitalized_name$();\n"
224 "}\n");
225
226 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER);
227 printer->Print(variables_,
228 "private void set$capitalized_name$Bytes(\n"
229 " com.google.protobuf.ByteString value) {\n");
230 if (CheckUtf8(descriptor_)) {
231 printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
232 }
233 printer->Print(variables_,
234 " $name$_ = value.toStringUtf8();\n"
235 " $set_has_field_bit_message$\n"
236 "}\n");
237 }
238
GenerateBuilderMembers(io::Printer * printer) const239 void ImmutableStringFieldLiteGenerator::GenerateBuilderMembers(
240 io::Printer* printer) const {
241 if (SupportFieldPresence(descriptor_)) {
242 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
243 printer->Print(
244 variables_,
245 "@java.lang.Override\n"
246 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
247 " return instance.has$capitalized_name$();\n"
248 "}\n");
249 printer->Annotate("{", "}", descriptor_);
250 }
251
252 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
253 printer->Print(
254 variables_,
255 "@java.lang.Override\n"
256 "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
257 " return instance.get$capitalized_name$();\n"
258 "}\n");
259 printer->Annotate("{", "}", descriptor_);
260
261 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
262 printer->Print(variables_,
263 "@java.lang.Override\n"
264 "$deprecation$public com.google.protobuf.ByteString\n"
265 " ${$get$capitalized_name$Bytes$}$() {\n"
266 " return instance.get$capitalized_name$Bytes();\n"
267 "}\n");
268 printer->Annotate("{", "}", descriptor_);
269
270 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
271 /* builder */ true);
272 printer->Print(variables_,
273 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
274 " java.lang.String value) {\n"
275 " copyOnWrite();\n"
276 " instance.set$capitalized_name$(value);\n"
277 " return this;\n"
278 "}\n");
279 printer->Annotate("{", "}", descriptor_);
280 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
281 /* builder */ true);
282 printer->Print(
283 variables_,
284 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
285 " copyOnWrite();\n"
286 " instance.clear$capitalized_name$();\n"
287 " return this;\n"
288 "}\n");
289 printer->Annotate("{", "}", descriptor_);
290
291 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER,
292 /* builder */ true);
293 printer->Print(
294 variables_,
295 "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
296 " com.google.protobuf.ByteString value) {\n"
297 " copyOnWrite();\n"
298 " instance.set$capitalized_name$Bytes(value);\n"
299 " return this;\n"
300 "}\n");
301 printer->Annotate("{", "}", descriptor_);
302 }
303
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const304 void ImmutableStringFieldLiteGenerator::GenerateFieldInfo(
305 io::Printer* printer, std::vector<uint16>* output) const {
306 WriteIntToUtf16CharSequence(descriptor_->number(), output);
307 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
308 output);
309 if (HasHasbit(descriptor_)) {
310 WriteIntToUtf16CharSequence(messageBitIndex_, output);
311 }
312 printer->Print(variables_, "\"$name$_\",\n");
313 }
314
GenerateInitializationCode(io::Printer * printer) const315 void ImmutableStringFieldLiteGenerator::GenerateInitializationCode(
316 io::Printer* printer) const {
317 printer->Print(variables_, "$name$_ = $default$;\n");
318 }
319
GetBoxedType() const320 std::string ImmutableStringFieldLiteGenerator::GetBoxedType() const {
321 return "java.lang.String";
322 }
323
324 // ===================================================================
325
ImmutableStringOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)326 ImmutableStringOneofFieldLiteGenerator::ImmutableStringOneofFieldLiteGenerator(
327 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
328 : ImmutableStringFieldLiteGenerator(descriptor, messageBitIndex, context) {
329 const OneofGeneratorInfo* info =
330 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
331 SetCommonOneofVariables(descriptor, info, &variables_);
332 }
333
334 ImmutableStringOneofFieldLiteGenerator::
~ImmutableStringOneofFieldLiteGenerator()335 ~ImmutableStringOneofFieldLiteGenerator() {}
336
GenerateMembers(io::Printer * printer) const337 void ImmutableStringOneofFieldLiteGenerator::GenerateMembers(
338 io::Printer* printer) const {
339 PrintExtraFieldInfo(variables_, printer);
340
341 if (SupportFieldPresence(descriptor_)) {
342 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
343 printer->Print(
344 variables_,
345 "@java.lang.Override\n"
346 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
347 " return $has_oneof_case_message$;\n"
348 "}\n");
349 printer->Annotate("{", "}", descriptor_);
350 }
351
352 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
353 printer->Print(
354 variables_,
355 "@java.lang.Override\n"
356 "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
357 " java.lang.String ref $default_init$;\n"
358 " if ($has_oneof_case_message$) {\n"
359 " ref = (java.lang.String) $oneof_name$_;\n"
360 " }\n"
361 " return ref;\n"
362 "}\n");
363 printer->Annotate("{", "}", descriptor_);
364
365 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
366 printer->Print(variables_,
367 "@java.lang.Override\n"
368 "$deprecation$public com.google.protobuf.ByteString\n"
369 " ${$get$capitalized_name$Bytes$}$() {\n"
370 " java.lang.String ref $default_init$;\n"
371 " if ($has_oneof_case_message$) {\n"
372 " ref = (java.lang.String) $oneof_name$_;\n"
373 " }\n"
374 " return com.google.protobuf.ByteString.copyFromUtf8(ref);\n"
375 "}\n");
376 printer->Annotate("{", "}", descriptor_);
377
378 WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
379 printer->Print(variables_,
380 "private void ${$set$capitalized_name$$}$(\n"
381 " java.lang.String value) {\n"
382 "$null_check$"
383 " $set_oneof_case_message$;\n"
384 " $oneof_name$_ = value;\n"
385 "}\n");
386 printer->Annotate("{", "}", descriptor_);
387 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
388 printer->Print(variables_,
389 "private void ${$clear$capitalized_name$$}$() {\n"
390 " if ($has_oneof_case_message$) {\n"
391 " $clear_oneof_case_message$;\n"
392 " $oneof_name$_ = null;\n"
393 " }\n"
394 "}\n");
395 printer->Annotate("{", "}", descriptor_);
396
397 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER);
398 printer->Print(variables_,
399 "private void ${$set$capitalized_name$Bytes$}$(\n"
400 " com.google.protobuf.ByteString value) {\n");
401 printer->Annotate("{", "}", descriptor_);
402 if (CheckUtf8(descriptor_)) {
403 printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
404 }
405 printer->Print(variables_,
406 " $oneof_name$_ = value.toStringUtf8();\n"
407 " $set_oneof_case_message$;\n"
408 "}\n");
409 }
410
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const411 void ImmutableStringOneofFieldLiteGenerator::GenerateFieldInfo(
412 io::Printer* printer, std::vector<uint16>* output) const {
413 WriteIntToUtf16CharSequence(descriptor_->number(), output);
414 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
415 output);
416 WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
417 }
418
GenerateBuilderMembers(io::Printer * printer) const419 void ImmutableStringOneofFieldLiteGenerator::GenerateBuilderMembers(
420 io::Printer* printer) const {
421 if (SupportFieldPresence(descriptor_)) {
422 WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
423 printer->Print(
424 variables_,
425 "@java.lang.Override\n"
426 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
427 " return instance.has$capitalized_name$();\n"
428 "}\n");
429 printer->Annotate("{", "}", descriptor_);
430 }
431
432 WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
433 printer->Print(
434 variables_,
435 "@java.lang.Override\n"
436 "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n"
437 " return instance.get$capitalized_name$();\n"
438 "}\n");
439 printer->Annotate("{", "}", descriptor_);
440
441 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER);
442 printer->Print(variables_,
443 "@java.lang.Override\n"
444 "$deprecation$public com.google.protobuf.ByteString\n"
445 " ${$get$capitalized_name$Bytes$}$() {\n"
446 " return instance.get$capitalized_name$Bytes();\n"
447 "}\n");
448 printer->Annotate("{", "}", descriptor_);
449
450 WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
451 /* builder */ true);
452 printer->Print(variables_,
453 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
454 " java.lang.String value) {\n"
455 " copyOnWrite();\n"
456 " instance.set$capitalized_name$(value);\n"
457 " return this;\n"
458 "}\n");
459 printer->Annotate("{", "}", descriptor_);
460 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
461 /* builder */ true);
462 printer->Print(
463 variables_,
464 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
465 " copyOnWrite();\n"
466 " instance.clear$capitalized_name$();\n"
467 " return this;\n"
468 "}\n");
469 printer->Annotate("{", "}", descriptor_);
470
471 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER,
472 /* builder */ true);
473 printer->Print(
474 variables_,
475 "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n"
476 " com.google.protobuf.ByteString value) {\n"
477 " copyOnWrite();\n"
478 " instance.set$capitalized_name$Bytes(value);\n"
479 " return this;\n"
480 "}\n");
481 printer->Annotate("{", "}", descriptor_);
482 }
483
484 // ===================================================================
485
486 RepeatedImmutableStringFieldLiteGenerator::
RepeatedImmutableStringFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)487 RepeatedImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor,
488 int messageBitIndex,
489 Context* context)
490 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
491 SetPrimitiveVariables(descriptor, messageBitIndex, 0,
492 context->GetFieldGeneratorInfo(descriptor),
493 name_resolver_, &variables_);
494 }
495
496 RepeatedImmutableStringFieldLiteGenerator::
~RepeatedImmutableStringFieldLiteGenerator()497 ~RepeatedImmutableStringFieldLiteGenerator() {}
498
GetNumBitsForMessage() const499 int RepeatedImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const {
500 return 0;
501 }
502
GenerateInterfaceMembers(io::Printer * printer) const503 void RepeatedImmutableStringFieldLiteGenerator::GenerateInterfaceMembers(
504 io::Printer* printer) const {
505 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
506 printer->Print(variables_,
507 "$deprecation$java.util.List<java.lang.String>\n"
508 " get$capitalized_name$List();\n");
509 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
510 printer->Print(variables_,
511 "$deprecation$int get$capitalized_name$Count();\n");
512 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
513 printer->Print(
514 variables_,
515 "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
516 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
517 printer->Print(variables_,
518 "$deprecation$com.google.protobuf.ByteString\n"
519 " get$capitalized_name$Bytes(int index);\n");
520 }
521
GenerateMembers(io::Printer * printer) const522 void RepeatedImmutableStringFieldLiteGenerator::GenerateMembers(
523 io::Printer* printer) const {
524 printer->Print(
525 variables_,
526 "private com.google.protobuf.Internal.ProtobufList<java.lang.String> "
527 "$name$_;\n");
528 PrintExtraFieldInfo(variables_, printer);
529 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
530 printer->Print(variables_,
531 "@java.lang.Override\n"
532 "$deprecation$public java.util.List<java.lang.String> "
533 "${$get$capitalized_name$List$}$() {\n"
534 " return $name$_;\n" // note: unmodifiable list
535 "}\n");
536 printer->Annotate("{", "}", descriptor_);
537 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
538 printer->Print(
539 variables_,
540 "@java.lang.Override\n"
541 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
542 " return $name$_.size();\n"
543 "}\n");
544 printer->Annotate("{", "}", descriptor_);
545 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
546 printer->Print(variables_,
547 "@java.lang.Override\n"
548 "$deprecation$public java.lang.String "
549 "${$get$capitalized_name$$}$(int index) {\n"
550 " return $name$_.get(index);\n"
551 "}\n");
552 printer->Annotate("{", "}", descriptor_);
553 WriteFieldStringBytesAccessorDocComment(printer, descriptor_,
554 LIST_INDEXED_GETTER);
555 printer->Print(variables_,
556 "@java.lang.Override\n"
557 "$deprecation$public com.google.protobuf.ByteString\n"
558 " ${$get$capitalized_name$Bytes$}$(int index) {\n"
559 " return com.google.protobuf.ByteString.copyFromUtf8(\n"
560 " $name$_.get(index));\n"
561 "}\n");
562 printer->Annotate("{", "}", descriptor_);
563
564 printer->Print(
565 variables_,
566 "private void ensure$capitalized_name$IsMutable() {\n"
567 // Use a temporary to avoid a redundant iget-object.
568 " com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =\n"
569 " $name$_;"
570 " if (!tmp.isModifiable()) {\n"
571 " $name$_ =\n"
572 " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
573 " }\n"
574 "}\n");
575
576 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
577 printer->Print(variables_,
578 "private void set$capitalized_name$(\n"
579 " int index, java.lang.String value) {\n"
580 "$null_check$"
581 " ensure$capitalized_name$IsMutable();\n"
582 " $name$_.set(index, value);\n"
583 "}\n");
584 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
585 printer->Print(variables_,
586 "private void add$capitalized_name$(\n"
587 " java.lang.String value) {\n"
588 "$null_check$"
589 " ensure$capitalized_name$IsMutable();\n"
590 " $name$_.add(value);\n"
591 "}\n");
592 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
593 printer->Print(variables_,
594 "private void addAll$capitalized_name$(\n"
595 " java.lang.Iterable<java.lang.String> values) {\n"
596 " ensure$capitalized_name$IsMutable();\n"
597 " com.google.protobuf.AbstractMessageLite.addAll(\n"
598 " values, $name$_);\n"
599 "}\n");
600 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
601 printer->Print(variables_,
602 "private void clear$capitalized_name$() {\n"
603 " $name$_ = $empty_list$;\n"
604 "}\n");
605
606 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER);
607 printer->Print(variables_,
608 "private void add$capitalized_name$Bytes(\n"
609 " com.google.protobuf.ByteString value) {\n");
610 if (CheckUtf8(descriptor_)) {
611 printer->Print(variables_, " checkByteStringIsUtf8(value);\n");
612 }
613 printer->Print(variables_,
614 " ensure$capitalized_name$IsMutable();\n"
615 " $name$_.add(value.toStringUtf8());\n"
616 "}\n");
617 }
618
GenerateBuilderMembers(io::Printer * printer) const619 void RepeatedImmutableStringFieldLiteGenerator::GenerateBuilderMembers(
620 io::Printer* printer) const {
621 WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
622 printer->Print(variables_,
623 "@java.lang.Override\n"
624 "$deprecation$public java.util.List<java.lang.String>\n"
625 " ${$get$capitalized_name$List$}$() {\n"
626 " return java.util.Collections.unmodifiableList(\n"
627 " instance.get$capitalized_name$List());\n"
628 "}\n");
629 printer->Annotate("{", "}", descriptor_);
630 WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
631 printer->Print(
632 variables_,
633 "@java.lang.Override\n"
634 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
635 " return instance.get$capitalized_name$Count();\n"
636 "}\n");
637 printer->Annotate("{", "}", descriptor_);
638 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
639 printer->Print(variables_,
640 "@java.lang.Override\n"
641 "$deprecation$public java.lang.String "
642 "${$get$capitalized_name$$}$(int index) {\n"
643 " return instance.get$capitalized_name$(index);\n"
644 "}\n");
645 printer->Annotate("{", "}", descriptor_);
646 WriteFieldStringBytesAccessorDocComment(printer, descriptor_,
647 LIST_INDEXED_GETTER);
648 printer->Print(variables_,
649 "@java.lang.Override\n"
650 "$deprecation$public com.google.protobuf.ByteString\n"
651 " ${$get$capitalized_name$Bytes$}$(int index) {\n"
652 " return instance.get$capitalized_name$Bytes(index);\n"
653 "}\n");
654 printer->Annotate("{", "}", descriptor_);
655 WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
656 /* builder */ true);
657 printer->Print(variables_,
658 "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
659 " int index, java.lang.String value) {\n"
660 " copyOnWrite();\n"
661 " instance.set$capitalized_name$(index, value);\n"
662 " return this;\n"
663 "}\n");
664 printer->Annotate("{", "}", descriptor_);
665 WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
666 /* builder */ true);
667 printer->Print(variables_,
668 "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
669 " java.lang.String value) {\n"
670 " copyOnWrite();\n"
671 " instance.add$capitalized_name$(value);\n"
672 " return this;\n"
673 "}\n");
674 printer->Annotate("{", "}", descriptor_);
675 WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
676 /* builder */ true);
677 printer->Print(variables_,
678 "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
679 " java.lang.Iterable<java.lang.String> values) {\n"
680 " copyOnWrite();\n"
681 " instance.addAll$capitalized_name$(values);\n"
682 " return this;\n"
683 "}\n");
684 printer->Annotate("{", "}", descriptor_);
685 WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
686 /* builder */ true);
687 printer->Print(
688 variables_,
689 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
690 " copyOnWrite();\n"
691 " instance.clear$capitalized_name$();\n"
692 " return this;\n"
693 "}\n");
694 printer->Annotate("{", "}", descriptor_);
695
696 WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER,
697 /* builder */ true);
698 printer->Print(
699 variables_,
700 "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n"
701 " com.google.protobuf.ByteString value) {\n"
702 " copyOnWrite();\n"
703 " instance.add$capitalized_name$Bytes(value);\n"
704 " return this;\n"
705 "}\n");
706 printer->Annotate("{", "}", descriptor_);
707 }
708
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const709 void RepeatedImmutableStringFieldLiteGenerator::GenerateFieldInfo(
710 io::Printer* printer, std::vector<uint16>* output) const {
711 WriteIntToUtf16CharSequence(descriptor_->number(), output);
712 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
713 output);
714 printer->Print(variables_, "\"$name$_\",\n");
715 }
716
GenerateInitializationCode(io::Printer * printer) const717 void RepeatedImmutableStringFieldLiteGenerator::GenerateInitializationCode(
718 io::Printer* printer) const {
719 printer->Print(variables_, "$name$_ = $empty_list$;\n");
720 }
721
GetBoxedType() const722 std::string RepeatedImmutableStringFieldLiteGenerator::GetBoxedType() const {
723 return "java.lang.String";
724 }
725
726 } // namespace java
727 } // namespace compiler
728 } // namespace protobuf
729 } // namespace google
730