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