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