• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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