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.h>
46#include <google/protobuf/io/printer.h>
47#include <google/protobuf/wire_format.h>
48#include <google/protobuf/stubs/strutil.h>
49
50namespace google {
51namespace protobuf {
52namespace compiler {
53namespace java {
54
55using internal::WireFormat;
56using internal::WireFormatLite;
57
58namespace {
59
60void SetPrimitiveVariables(const FieldDescriptor* descriptor,
61                           int messageBitIndex,
62                           int builderBitIndex,
63                           const FieldGeneratorInfo* info,
64                           ClassNameResolver* name_resolver,
65                           map<string, string>* variables) {
66  SetCommonFieldVariables(descriptor, info, variables);
67
68  (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
69
70  (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
71  (*variables)["default_init"] =
72      "= " + ImmutableDefaultValue(descriptor, name_resolver);
73  (*variables)["capitalized_type"] = "String";
74  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
75  (*variables)["tag_size"] = SimpleItoa(
76      WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
77  (*variables)["null_check"] =
78      "  if (value == null) {\n"
79      "    throw new NullPointerException();\n"
80      "  }\n";
81  (*variables)["writeString"] =
82      "com.google.protobuf.GeneratedMessage.writeString";
83  (*variables)["computeStringSize"] =
84      "com.google.protobuf.GeneratedMessage.computeStringSize";
85
86  // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
87  // by the proto compiler
88  (*variables)["deprecation"] = descriptor->options().deprecated()
89      ? "@java.lang.Deprecated " : "";
90  (*variables)["on_changed"] = "onChanged();";
91
92  if (SupportFieldPresence(descriptor->file())) {
93    // For singular messages and builders, one bit is used for the hasField bit.
94    (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
95    (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
96
97    // Note that these have a trailing ";".
98    (*variables)["set_has_field_bit_message"] =
99        GenerateSetBit(messageBitIndex) + ";";
100    (*variables)["set_has_field_bit_builder"] =
101        GenerateSetBit(builderBitIndex) + ";";
102    (*variables)["clear_has_field_bit_builder"] =
103        GenerateClearBit(builderBitIndex) + ";";
104
105    (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
106  } else {
107    (*variables)["set_has_field_bit_message"] = "";
108    (*variables)["set_has_field_bit_builder"] = "";
109    (*variables)["clear_has_field_bit_builder"] = "";
110
111    (*variables)["is_field_present_message"] =
112        "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
113  }
114
115  // For repeated builders, one bit is used for whether the array is immutable.
116  (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
117  (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
118  (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
119
120  // For repeated fields, one bit is used for whether the array is immutable
121  // in the parsing constructor.
122  (*variables)["get_mutable_bit_parser"] =
123      GenerateGetBitMutableLocal(builderBitIndex);
124  (*variables)["set_mutable_bit_parser"] =
125      GenerateSetBitMutableLocal(builderBitIndex);
126
127  (*variables)["get_has_field_bit_from_local"] =
128      GenerateGetBitFromLocal(builderBitIndex);
129  (*variables)["set_has_field_bit_to_local"] =
130      GenerateSetBitToLocal(messageBitIndex);
131}
132
133}  // namespace
134
135// ===================================================================
136
137ImmutableStringFieldGenerator::
138ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
139                              int messageBitIndex,
140                              int builderBitIndex,
141                              Context* context)
142  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
143    builderBitIndex_(builderBitIndex), context_(context),
144    name_resolver_(context->GetNameResolver()) {
145  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
146                        context->GetFieldGeneratorInfo(descriptor),
147                        name_resolver_, &variables_);
148}
149
150ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
151
152int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
153  return 1;
154}
155
156int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
157  return 1;
158}
159
160// A note about how strings are handled. This code used to just store a String
161// in the Message. This had two issues:
162//
163//  1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
164//     strings, but rather fields that were raw bytes incorrectly marked
165//     as strings in the proto file. This is common because in the proto1
166//     syntax, string was the way to indicate bytes and C++ engineers can
167//     easily make this mistake without affecting the C++ API. By converting to
168//     strings immediately, some java code might corrupt these byte arrays as
169//     it passes through a java server even if the field was never accessed by
170//     application code.
171//
172//  2. There's a performance hit to converting between bytes and strings and
173//     it many cases, the field is never even read by the application code. This
174//     avoids unnecessary conversions in the common use cases.
175//
176// So now, the field for String is maintained as an Object reference which can
177// either store a String or a ByteString. The code uses an instanceof check
178// to see which one it has and converts to the other one if needed. It remembers
179// the last value requested (in a thread safe manner) as this is most likely
180// the one needed next. The thread safety is such that if two threads both
181// convert the field because the changes made by each thread were not visible to
182// the other, they may cause a conversion to happen more times than would
183// otherwise be necessary. This was deemed better than adding synchronization
184// overhead. It will not cause any corruption issues or affect the behavior of
185// the API. The instanceof check is also highly optimized in the JVM and we
186// decided it was better to reduce the memory overhead by not having two
187// separate fields but rather use dynamic type checking.
188//
189// For single fields, the logic for this is done inside the generated code. For
190// repeated fields, the logic is done in LazyStringArrayList and
191// UnmodifiableLazyStringList.
192void ImmutableStringFieldGenerator::
193GenerateInterfaceMembers(io::Printer* printer) const {
194  if (SupportFieldPresence(descriptor_->file())) {
195    WriteFieldDocComment(printer, descriptor_);
196    printer->Print(variables_,
197      "$deprecation$boolean has$capitalized_name$();\n");
198  }
199  WriteFieldDocComment(printer, descriptor_);
200  printer->Print(variables_,
201    "$deprecation$java.lang.String get$capitalized_name$();\n");
202  WriteFieldDocComment(printer, descriptor_);
203  printer->Print(variables_,
204    "$deprecation$com.google.protobuf.ByteString\n"
205    "    get$capitalized_name$Bytes();\n");
206}
207
208void ImmutableStringFieldGenerator::
209GenerateMembers(io::Printer* printer) const {
210  printer->Print(variables_,
211    "private volatile java.lang.Object $name$_;\n");
212  PrintExtraFieldInfo(variables_, printer);
213
214  if (SupportFieldPresence(descriptor_->file())) {
215    WriteFieldDocComment(printer, descriptor_);
216    printer->Print(variables_,
217      "$deprecation$public boolean has$capitalized_name$() {\n"
218      "  return $get_has_field_bit_message$;\n"
219      "}\n");
220  }
221
222  WriteFieldDocComment(printer, descriptor_);
223  printer->Print(variables_,
224    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
225    "  java.lang.Object ref = $name$_;\n"
226    "  if (ref instanceof java.lang.String) {\n"
227    "    return (java.lang.String) ref;\n"
228    "  } else {\n"
229    "    com.google.protobuf.ByteString bs = \n"
230    "        (com.google.protobuf.ByteString) ref;\n"
231      "    java.lang.String s = bs.toStringUtf8();\n");
232  if (CheckUtf8(descriptor_)) {
233    printer->Print(variables_,
234      "    $name$_ = s;\n");
235  } else {
236    printer->Print(variables_,
237      "    if (bs.isValidUtf8()) {\n"
238      "      $name$_ = s;\n"
239      "    }\n");
240  }
241  printer->Print(variables_,
242    "    return s;\n"
243    "  }\n"
244    "}\n");
245  WriteFieldDocComment(printer, descriptor_);
246  printer->Print(variables_,
247    "$deprecation$public com.google.protobuf.ByteString\n"
248    "    get$capitalized_name$Bytes() {\n"
249    "  java.lang.Object ref = $name$_;\n"
250    "  if (ref instanceof java.lang.String) {\n"
251    "    com.google.protobuf.ByteString b = \n"
252    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
253    "            (java.lang.String) ref);\n"
254    "    $name$_ = b;\n"
255    "    return b;\n"
256    "  } else {\n"
257    "    return (com.google.protobuf.ByteString) ref;\n"
258    "  }\n"
259    "}\n");
260}
261
262void ImmutableStringFieldGenerator::
263GenerateBuilderMembers(io::Printer* printer) const {
264  printer->Print(variables_,
265    "private java.lang.Object $name$_ $default_init$;\n");
266  if (SupportFieldPresence(descriptor_->file())) {
267    WriteFieldDocComment(printer, descriptor_);
268    printer->Print(variables_,
269      "$deprecation$public boolean has$capitalized_name$() {\n"
270      "  return $get_has_field_bit_builder$;\n"
271      "}\n");
272  }
273
274  WriteFieldDocComment(printer, descriptor_);
275  printer->Print(variables_,
276    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
277    "  java.lang.Object ref = $name$_;\n"
278    "  if (!(ref instanceof java.lang.String)) {\n"
279    "    com.google.protobuf.ByteString bs =\n"
280    "        (com.google.protobuf.ByteString) ref;\n"
281    "    java.lang.String s = bs.toStringUtf8();\n");
282  if (CheckUtf8(descriptor_)) {
283    printer->Print(variables_,
284      "    $name$_ = s;\n");
285  } else {
286    printer->Print(variables_,
287      "    if (bs.isValidUtf8()) {\n"
288      "      $name$_ = s;\n"
289      "    }\n");
290  }
291  printer->Print(variables_,
292    "    return s;\n"
293    "  } else {\n"
294    "    return (java.lang.String) ref;\n"
295    "  }\n"
296    "}\n");
297
298  WriteFieldDocComment(printer, descriptor_);
299  printer->Print(variables_,
300    "$deprecation$public com.google.protobuf.ByteString\n"
301    "    get$capitalized_name$Bytes() {\n"
302    "  java.lang.Object ref = $name$_;\n"
303    "  if (ref instanceof String) {\n"
304    "    com.google.protobuf.ByteString b = \n"
305    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
306    "            (java.lang.String) ref);\n"
307    "    $name$_ = b;\n"
308    "    return b;\n"
309    "  } else {\n"
310    "    return (com.google.protobuf.ByteString) ref;\n"
311    "  }\n"
312    "}\n");
313
314  WriteFieldDocComment(printer, descriptor_);
315  printer->Print(variables_,
316    "$deprecation$public Builder set$capitalized_name$(\n"
317    "    java.lang.String value) {\n"
318    "$null_check$"
319    "  $set_has_field_bit_builder$\n"
320    "  $name$_ = value;\n"
321    "  $on_changed$\n"
322    "  return this;\n"
323    "}\n");
324  WriteFieldDocComment(printer, descriptor_);
325  printer->Print(variables_,
326    "$deprecation$public Builder clear$capitalized_name$() {\n"
327    "  $clear_has_field_bit_builder$\n");
328  // The default value is not a simple literal so we want to avoid executing
329  // it multiple times.  Instead, get the default out of the default instance.
330  printer->Print(variables_,
331    "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
332  printer->Print(variables_,
333    "  $on_changed$\n"
334    "  return this;\n"
335    "}\n");
336
337  WriteFieldDocComment(printer, descriptor_);
338  printer->Print(variables_,
339    "$deprecation$public Builder set$capitalized_name$Bytes(\n"
340    "    com.google.protobuf.ByteString value) {\n"
341    "$null_check$");
342  if (CheckUtf8(descriptor_)) {
343    printer->Print(variables_,
344      "  checkByteStringIsUtf8(value);\n");
345  }
346  printer->Print(variables_,
347    "  $set_has_field_bit_builder$\n"
348    "  $name$_ = value;\n"
349    "  $on_changed$\n"
350    "  return this;\n"
351    "}\n");
352}
353
354void ImmutableStringFieldGenerator::
355GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
356  // noop for primitives
357}
358
359void ImmutableStringFieldGenerator::
360GenerateInitializationCode(io::Printer* printer) const {
361  printer->Print(variables_, "$name$_ = $default$;\n");
362}
363
364void ImmutableStringFieldGenerator::
365GenerateBuilderClearCode(io::Printer* printer) const {
366  printer->Print(variables_,
367    "$name$_ = $default$;\n"
368    "$clear_has_field_bit_builder$\n");
369}
370
371void ImmutableStringFieldGenerator::
372GenerateMergingCode(io::Printer* printer) const {
373  if (SupportFieldPresence(descriptor_->file())) {
374    // Allow a slight breach of abstraction here in order to avoid forcing
375    // all string fields to Strings when copying fields from a Message.
376    printer->Print(variables_,
377      "if (other.has$capitalized_name$()) {\n"
378      "  $set_has_field_bit_builder$\n"
379      "  $name$_ = other.$name$_;\n"
380      "  $on_changed$\n"
381      "}\n");
382  } else {
383    printer->Print(variables_,
384      "if (!other.get$capitalized_name$().isEmpty()) {\n"
385      "  $name$_ = other.$name$_;\n"
386      "  $on_changed$\n"
387      "}\n");
388  }
389}
390
391void ImmutableStringFieldGenerator::
392GenerateBuildingCode(io::Printer* printer) const {
393  if (SupportFieldPresence(descriptor_->file())) {
394    printer->Print(variables_,
395      "if ($get_has_field_bit_from_local$) {\n"
396      "  $set_has_field_bit_to_local$;\n"
397      "}\n");
398  }
399  printer->Print(variables_,
400    "result.$name$_ = $name$_;\n");
401}
402
403void ImmutableStringFieldGenerator::
404GenerateParsingCode(io::Printer* printer) const {
405  if (CheckUtf8(descriptor_)) {
406    printer->Print(variables_,
407      "java.lang.String s = input.readStringRequireUtf8();\n"
408      "$set_has_field_bit_message$\n"
409      "$name$_ = s;\n");
410  } else {
411    printer->Print(variables_,
412      "com.google.protobuf.ByteString bs = input.readBytes();\n"
413      "$set_has_field_bit_message$\n"
414      "$name$_ = bs;\n");
415  }
416}
417
418void ImmutableStringFieldGenerator::
419GenerateParsingDoneCode(io::Printer* printer) const {
420  // noop for strings.
421}
422
423void ImmutableStringFieldGenerator::
424GenerateSerializationCode(io::Printer* printer) const {
425  printer->Print(variables_,
426    "if ($is_field_present_message$) {\n"
427    "  $writeString$(output, $number$, $name$_);\n"
428    "}\n");
429}
430
431void ImmutableStringFieldGenerator::
432GenerateSerializedSizeCode(io::Printer* printer) const {
433  printer->Print(variables_,
434    "if ($is_field_present_message$) {\n"
435    "  size += $computeStringSize$($number$, $name$_);\n"
436    "}\n");
437}
438
439void ImmutableStringFieldGenerator::
440GenerateEqualsCode(io::Printer* printer) const {
441  printer->Print(variables_,
442    "result = result && get$capitalized_name$()\n"
443    "    .equals(other.get$capitalized_name$());\n");
444}
445
446void ImmutableStringFieldGenerator::
447GenerateHashCode(io::Printer* printer) const {
448  printer->Print(variables_,
449    "hash = (37 * hash) + $constant_name$;\n");
450  printer->Print(variables_,
451    "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
452}
453
454string ImmutableStringFieldGenerator::GetBoxedType() const {
455  return "java.lang.String";
456}
457
458// ===================================================================
459
460ImmutableStringOneofFieldGenerator::
461ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
462                                   int messageBitIndex,
463                                   int builderBitIndex,
464                                   Context* context)
465    : ImmutableStringFieldGenerator(
466          descriptor, messageBitIndex, builderBitIndex, context) {
467  const OneofGeneratorInfo* info =
468      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
469  SetCommonOneofVariables(descriptor, info, &variables_);
470}
471
472ImmutableStringOneofFieldGenerator::
473~ImmutableStringOneofFieldGenerator() {}
474
475void ImmutableStringOneofFieldGenerator::
476GenerateMembers(io::Printer* printer) const {
477  PrintExtraFieldInfo(variables_, printer);
478
479  if (SupportFieldPresence(descriptor_->file())) {
480  WriteFieldDocComment(printer, descriptor_);
481  printer->Print(variables_,
482    "$deprecation$public boolean has$capitalized_name$() {\n"
483    "  return $has_oneof_case_message$;\n"
484    "}\n");
485  }
486
487  WriteFieldDocComment(printer, descriptor_);
488  printer->Print(variables_,
489    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
490    "  java.lang.Object ref $default_init$;\n"
491    "  if ($has_oneof_case_message$) {\n"
492    "    ref = $oneof_name$_;\n"
493    "  }\n"
494    "  if (ref instanceof java.lang.String) {\n"
495    "    return (java.lang.String) ref;\n"
496    "  } else {\n"
497    "    com.google.protobuf.ByteString bs = \n"
498    "        (com.google.protobuf.ByteString) ref;\n"
499    "    java.lang.String s = bs.toStringUtf8();\n");
500  if (CheckUtf8(descriptor_)) {
501    printer->Print(variables_,
502    "    if ($has_oneof_case_message$) {\n"
503    "      $oneof_name$_ = s;\n"
504    "    }\n");
505  } else {
506    printer->Print(variables_,
507    "    if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
508    "      $oneof_name$_ = s;\n"
509    "    }\n");
510  }
511  printer->Print(variables_,
512    "    return s;\n"
513    "  }\n"
514    "}\n");
515  WriteFieldDocComment(printer, descriptor_);
516
517  printer->Print(variables_,
518    "$deprecation$public com.google.protobuf.ByteString\n"
519    "    get$capitalized_name$Bytes() {\n"
520    "  java.lang.Object ref $default_init$;\n"
521    "  if ($has_oneof_case_message$) {\n"
522    "    ref = $oneof_name$_;\n"
523    "  }\n"
524    "  if (ref instanceof java.lang.String) {\n"
525    "    com.google.protobuf.ByteString b = \n"
526    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
527    "            (java.lang.String) ref);\n"
528    "    if ($has_oneof_case_message$) {\n"
529    "      $oneof_name$_ = b;\n"
530    "    }\n"
531    "    return b;\n"
532    "  } else {\n"
533    "    return (com.google.protobuf.ByteString) ref;\n"
534    "  }\n"
535    "}\n");
536}
537
538void ImmutableStringOneofFieldGenerator::
539GenerateBuilderMembers(io::Printer* printer) const {
540  if (SupportFieldPresence(descriptor_->file())) {
541    WriteFieldDocComment(printer, descriptor_);
542    printer->Print(variables_,
543      "$deprecation$public boolean has$capitalized_name$() {\n"
544      "  return $has_oneof_case_message$;\n"
545      "}\n");
546  }
547
548  WriteFieldDocComment(printer, descriptor_);
549  printer->Print(variables_,
550    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
551    "  java.lang.Object ref $default_init$;\n"
552    "  if ($has_oneof_case_message$) {\n"
553    "    ref = $oneof_name$_;\n"
554    "  }\n"
555    "  if (!(ref instanceof java.lang.String)) {\n"
556    "    com.google.protobuf.ByteString bs =\n"
557    "        (com.google.protobuf.ByteString) ref;\n"
558    "    java.lang.String s = bs.toStringUtf8();\n"
559    "    if ($has_oneof_case_message$) {\n");
560  if (CheckUtf8(descriptor_)) {
561    printer->Print(variables_,
562      "      $oneof_name$_ = s;\n");
563  } else {
564    printer->Print(variables_,
565      "      if (bs.isValidUtf8()) {\n"
566      "        $oneof_name$_ = s;\n"
567      "      }\n");
568  }
569  printer->Print(variables_,
570    "    }\n"
571    "    return s;\n"
572    "  } else {\n"
573    "    return (java.lang.String) ref;\n"
574    "  }\n"
575    "}\n");
576
577  WriteFieldDocComment(printer, descriptor_);
578  printer->Print(variables_,
579    "$deprecation$public com.google.protobuf.ByteString\n"
580    "    get$capitalized_name$Bytes() {\n"
581    "  java.lang.Object ref $default_init$;\n"
582    "  if ($has_oneof_case_message$) {\n"
583    "    ref = $oneof_name$_;\n"
584    "  }\n"
585    "  if (ref instanceof String) {\n"
586    "    com.google.protobuf.ByteString b = \n"
587    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
588    "            (java.lang.String) ref);\n"
589    "    if ($has_oneof_case_message$) {\n"
590    "      $oneof_name$_ = b;\n"
591    "    }\n"
592    "    return b;\n"
593    "  } else {\n"
594    "    return (com.google.protobuf.ByteString) ref;\n"
595    "  }\n"
596    "}\n");
597
598  WriteFieldDocComment(printer, descriptor_);
599  printer->Print(variables_,
600    "$deprecation$public Builder set$capitalized_name$(\n"
601    "    java.lang.String value) {\n"
602    "$null_check$"
603    "  $set_oneof_case_message$;\n"
604    "  $oneof_name$_ = value;\n"
605    "  $on_changed$\n"
606    "  return this;\n"
607    "}\n");
608  WriteFieldDocComment(printer, descriptor_);
609  printer->Print(variables_,
610    "$deprecation$public Builder clear$capitalized_name$() {\n"
611    "  if ($has_oneof_case_message$) {\n"
612    "    $clear_oneof_case_message$;\n"
613    "    $oneof_name$_ = null;\n"
614    "    $on_changed$\n"
615    "  }\n"
616    "  return this;\n"
617    "}\n");
618
619  WriteFieldDocComment(printer, descriptor_);
620  printer->Print(variables_,
621    "$deprecation$public Builder set$capitalized_name$Bytes(\n"
622    "    com.google.protobuf.ByteString value) {\n"
623    "$null_check$");
624  if (CheckUtf8(descriptor_)) {
625    printer->Print(variables_,
626      "  checkByteStringIsUtf8(value);\n");
627  }
628  printer->Print(variables_,
629    "  $set_oneof_case_message$;\n"
630    "  $oneof_name$_ = value;\n"
631    "  $on_changed$\n"
632    "  return this;\n"
633    "}\n");
634}
635
636void ImmutableStringOneofFieldGenerator::
637GenerateMergingCode(io::Printer* printer) const {
638  // Allow a slight breach of abstraction here in order to avoid forcing
639  // all string fields to Strings when copying fields from a Message.
640  printer->Print(variables_,
641    "$set_oneof_case_message$;\n"
642    "$oneof_name$_ = other.$oneof_name$_;\n"
643    "$on_changed$\n");
644}
645
646void ImmutableStringOneofFieldGenerator::
647GenerateBuildingCode(io::Printer* printer) const {
648  printer->Print(variables_,
649    "if ($has_oneof_case_message$) {\n"
650    "  result.$oneof_name$_ = $oneof_name$_;\n"
651    "}\n");
652}
653
654void ImmutableStringOneofFieldGenerator::
655GenerateParsingCode(io::Printer* printer) const {
656  if (CheckUtf8(descriptor_)) {
657    printer->Print(variables_,
658      "java.lang.String s = input.readStringRequireUtf8();\n"
659      "$set_oneof_case_message$;\n"
660      "$oneof_name$_ = s;\n");
661  } else {
662    printer->Print(variables_,
663      "com.google.protobuf.ByteString bs = input.readBytes();\n"
664      "$set_oneof_case_message$;\n"
665      "$oneof_name$_ = bs;\n");
666  }
667}
668
669void ImmutableStringOneofFieldGenerator::
670GenerateSerializationCode(io::Printer* printer) const {
671  printer->Print(variables_,
672    "if ($has_oneof_case_message$) {\n"
673    "  $writeString$(output, $number$, $oneof_name$_);\n"
674    "}\n");
675}
676
677void ImmutableStringOneofFieldGenerator::
678GenerateSerializedSizeCode(io::Printer* printer) const {
679  printer->Print(variables_,
680    "if ($has_oneof_case_message$) {\n"
681    "  size += $computeStringSize$($number$, $oneof_name$_);\n"
682    "}\n");
683}
684
685// ===================================================================
686
687RepeatedImmutableStringFieldGenerator::
688RepeatedImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
689                                      int messageBitIndex,
690                                      int builderBitIndex,
691                                      Context* context)
692  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
693    builderBitIndex_(builderBitIndex), context_(context),
694    name_resolver_(context->GetNameResolver()) {
695  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
696                        context->GetFieldGeneratorInfo(descriptor),
697                        name_resolver_, &variables_);
698}
699
700RepeatedImmutableStringFieldGenerator::
701~RepeatedImmutableStringFieldGenerator() {}
702
703int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const {
704  return 0;
705}
706
707int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
708  return 1;
709}
710
711void RepeatedImmutableStringFieldGenerator::
712GenerateInterfaceMembers(io::Printer* printer) const {
713  WriteFieldDocComment(printer, descriptor_);
714  printer->Print(variables_,
715    "$deprecation$com.google.protobuf.ProtocolStringList\n"
716    "    get$capitalized_name$List();\n");
717  WriteFieldDocComment(printer, descriptor_);
718  printer->Print(variables_,
719    "$deprecation$int get$capitalized_name$Count();\n");
720  WriteFieldDocComment(printer, descriptor_);
721  printer->Print(variables_,
722    "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
723  WriteFieldDocComment(printer, descriptor_);
724  printer->Print(variables_,
725    "$deprecation$com.google.protobuf.ByteString\n"
726    "    get$capitalized_name$Bytes(int index);\n");
727}
728
729
730void RepeatedImmutableStringFieldGenerator::
731GenerateMembers(io::Printer* printer) const {
732  printer->Print(variables_,
733    "private com.google.protobuf.LazyStringList $name$_;\n");
734  PrintExtraFieldInfo(variables_, printer);
735  WriteFieldDocComment(printer, descriptor_);
736  printer->Print(variables_,
737    "$deprecation$public com.google.protobuf.ProtocolStringList\n"
738    "    get$capitalized_name$List() {\n"
739    "  return $name$_;\n"   // note:  unmodifiable list
740    "}\n");
741  WriteFieldDocComment(printer, descriptor_);
742  printer->Print(variables_,
743    "$deprecation$public int get$capitalized_name$Count() {\n"
744    "  return $name$_.size();\n"
745    "}\n");
746  WriteFieldDocComment(printer, descriptor_);
747  printer->Print(variables_,
748    "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
749    "  return $name$_.get(index);\n"
750    "}\n");
751  WriteFieldDocComment(printer, descriptor_);
752  printer->Print(variables_,
753    "$deprecation$public com.google.protobuf.ByteString\n"
754    "    get$capitalized_name$Bytes(int index) {\n"
755    "  return $name$_.getByteString(index);\n"
756    "}\n");
757}
758
759void RepeatedImmutableStringFieldGenerator::
760GenerateBuilderMembers(io::Printer* printer) const {
761  // One field is the list and the bit field keeps track of whether the
762  // list is immutable. If it's immutable, the invariant is that it must
763  // either an instance of Collections.emptyList() or it's an ArrayList
764  // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
765  // a refererence to the underlying ArrayList. This invariant allows us to
766  // share instances of lists between protocol buffers avoiding expensive
767  // memory allocations. Note, immutable is a strong guarantee here -- not
768  // just that the list cannot be modified via the reference but that the
769  // list can never be modified.
770  printer->Print(variables_,
771    "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
772
773  printer->Print(variables_,
774    "private void ensure$capitalized_name$IsMutable() {\n"
775    "  if (!$get_mutable_bit_builder$) {\n"
776    "    $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
777    "    $set_mutable_bit_builder$;\n"
778    "   }\n"
779    "}\n");
780
781    // Note:  We return an unmodifiable list because otherwise the caller
782    //   could hold on to the returned list and modify it after the message
783    //   has been built, thus mutating the message which is supposed to be
784    //   immutable.
785  WriteFieldDocComment(printer, descriptor_);
786  printer->Print(variables_,
787    "$deprecation$public com.google.protobuf.ProtocolStringList\n"
788    "    get$capitalized_name$List() {\n"
789    "  return $name$_.getUnmodifiableView();\n"
790    "}\n");
791  WriteFieldDocComment(printer, descriptor_);
792  printer->Print(variables_,
793    "$deprecation$public int get$capitalized_name$Count() {\n"
794    "  return $name$_.size();\n"
795    "}\n");
796  WriteFieldDocComment(printer, descriptor_);
797  printer->Print(variables_,
798    "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
799    "  return $name$_.get(index);\n"
800    "}\n");
801  WriteFieldDocComment(printer, descriptor_);
802  printer->Print(variables_,
803    "$deprecation$public com.google.protobuf.ByteString\n"
804    "    get$capitalized_name$Bytes(int index) {\n"
805    "  return $name$_.getByteString(index);\n"
806    "}\n");
807  WriteFieldDocComment(printer, descriptor_);
808  printer->Print(variables_,
809    "$deprecation$public Builder set$capitalized_name$(\n"
810    "    int index, java.lang.String value) {\n"
811    "$null_check$"
812    "  ensure$capitalized_name$IsMutable();\n"
813    "  $name$_.set(index, value);\n"
814    "  $on_changed$\n"
815    "  return this;\n"
816    "}\n");
817  WriteFieldDocComment(printer, descriptor_);
818  printer->Print(variables_,
819    "$deprecation$public Builder add$capitalized_name$(\n"
820    "    java.lang.String value) {\n"
821    "$null_check$"
822    "  ensure$capitalized_name$IsMutable();\n"
823    "  $name$_.add(value);\n"
824    "  $on_changed$\n"
825    "  return this;\n"
826    "}\n");
827  WriteFieldDocComment(printer, descriptor_);
828  printer->Print(variables_,
829    "$deprecation$public Builder addAll$capitalized_name$(\n"
830    "    java.lang.Iterable<java.lang.String> values) {\n"
831    "  ensure$capitalized_name$IsMutable();\n"
832    "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
833    "      values, $name$_);\n"
834    "  $on_changed$\n"
835    "  return this;\n"
836    "}\n");
837  WriteFieldDocComment(printer, descriptor_);
838  printer->Print(variables_,
839    "$deprecation$public Builder clear$capitalized_name$() {\n"
840    "  $name$_ = $empty_list$;\n"
841    "  $clear_mutable_bit_builder$;\n"
842    "  $on_changed$\n"
843    "  return this;\n"
844    "}\n");
845
846  WriteFieldDocComment(printer, descriptor_);
847  printer->Print(variables_,
848    "$deprecation$public Builder add$capitalized_name$Bytes(\n"
849    "    com.google.protobuf.ByteString value) {\n"
850    "$null_check$");
851  if (CheckUtf8(descriptor_)) {
852    printer->Print(variables_,
853      "  checkByteStringIsUtf8(value);\n");
854  }
855  printer->Print(variables_,
856    "  ensure$capitalized_name$IsMutable();\n"
857    "  $name$_.add(value);\n"
858    "  $on_changed$\n"
859    "  return this;\n"
860    "}\n");
861}
862
863void RepeatedImmutableStringFieldGenerator::
864GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
865  // noop for primitives
866}
867
868void RepeatedImmutableStringFieldGenerator::
869GenerateInitializationCode(io::Printer* printer) const {
870  printer->Print(variables_, "$name$_ = $empty_list$;\n");
871}
872
873void RepeatedImmutableStringFieldGenerator::
874GenerateBuilderClearCode(io::Printer* printer) const {
875  printer->Print(variables_,
876    "$name$_ = $empty_list$;\n"
877    "$clear_mutable_bit_builder$;\n");
878}
879
880void RepeatedImmutableStringFieldGenerator::
881GenerateMergingCode(io::Printer* printer) const {
882  // The code below does two optimizations:
883  //   1. If the other list is empty, there's nothing to do. This ensures we
884  //      don't allocate a new array if we already have an immutable one.
885  //   2. If the other list is non-empty and our current list is empty, we can
886  //      reuse the other list which is guaranteed to be immutable.
887  printer->Print(variables_,
888    "if (!other.$name$_.isEmpty()) {\n"
889    "  if ($name$_.isEmpty()) {\n"
890    "    $name$_ = other.$name$_;\n"
891    "    $clear_mutable_bit_builder$;\n"
892    "  } else {\n"
893    "    ensure$capitalized_name$IsMutable();\n"
894    "    $name$_.addAll(other.$name$_);\n"
895    "  }\n"
896    "  $on_changed$\n"
897    "}\n");
898}
899
900void RepeatedImmutableStringFieldGenerator::
901GenerateBuildingCode(io::Printer* printer) const {
902  // The code below ensures that the result has an immutable list. If our
903  // list is immutable, we can just reuse it. If not, we make it immutable.
904
905  printer->Print(variables_,
906    "if ($get_mutable_bit_builder$) {\n"
907    "  $name$_ = $name$_.getUnmodifiableView();\n"
908    "  $clear_mutable_bit_builder$;\n"
909    "}\n"
910    "result.$name$_ = $name$_;\n");
911}
912
913void RepeatedImmutableStringFieldGenerator::
914GenerateParsingCode(io::Printer* printer) const {
915  if (CheckUtf8(descriptor_)) {
916    printer->Print(variables_,
917    "java.lang.String s = input.readStringRequireUtf8();\n");
918  } else {
919    printer->Print(variables_,
920    "com.google.protobuf.ByteString bs = input.readBytes();\n");
921  }
922  printer->Print(variables_,
923    "if (!$get_mutable_bit_parser$) {\n"
924    "  $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
925    "  $set_mutable_bit_parser$;\n"
926    "}\n");
927  if (CheckUtf8(descriptor_)) {
928    printer->Print(variables_,
929      "$name$_.add(s);\n");
930  } else {
931    printer->Print(variables_,
932      "$name$_.add(bs);\n");
933  }
934}
935
936void RepeatedImmutableStringFieldGenerator::
937GenerateParsingDoneCode(io::Printer* printer) const {
938  printer->Print(variables_,
939    "if ($get_mutable_bit_parser$) {\n"
940    "  $name$_ = $name$_.getUnmodifiableView();\n"
941    "}\n");
942}
943
944void RepeatedImmutableStringFieldGenerator::
945GenerateSerializationCode(io::Printer* printer) const {
946  printer->Print(variables_,
947    "for (int i = 0; i < $name$_.size(); i++) {\n"
948    "  $writeString$(output, $number$, $name$_.getRaw(i));\n"
949    "}\n");
950}
951
952void RepeatedImmutableStringFieldGenerator::
953GenerateSerializedSizeCode(io::Printer* printer) const {
954  printer->Print(variables_,
955    "{\n"
956    "  int dataSize = 0;\n");
957  printer->Indent();
958
959  printer->Print(variables_,
960    "for (int i = 0; i < $name$_.size(); i++) {\n"
961    "  dataSize += computeStringSizeNoTag($name$_.getRaw(i));\n"
962    "}\n");
963
964  printer->Print(
965      "size += dataSize;\n");
966
967  printer->Print(variables_,
968    "size += $tag_size$ * get$capitalized_name$List().size();\n");
969
970  printer->Outdent();
971  printer->Print("}\n");
972}
973
974void RepeatedImmutableStringFieldGenerator::
975GenerateEqualsCode(io::Printer* printer) const {
976  printer->Print(variables_,
977    "result = result && get$capitalized_name$List()\n"
978    "    .equals(other.get$capitalized_name$List());\n");
979}
980
981void RepeatedImmutableStringFieldGenerator::
982GenerateHashCode(io::Printer* printer) const {
983  printer->Print(variables_,
984    "if (get$capitalized_name$Count() > 0) {\n"
985    "  hash = (37 * hash) + $constant_name$;\n"
986    "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
987    "}\n");
988}
989
990string RepeatedImmutableStringFieldGenerator::GetBoxedType() const {
991  return "String";
992}
993
994}  // namespace java
995}  // namespace compiler
996}  // namespace protobuf
997}  // namespace google
998