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