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 | #include <google/protobuf/compiler/java/map_field.h> |
32 | |
33 | #include <google/protobuf/io/printer.h> |
34 | #include <google/protobuf/compiler/java/context.h> |
35 | #include <google/protobuf/compiler/java/doc_comment.h> |
36 | #include <google/protobuf/compiler/java/helpers.h> |
37 | #include <google/protobuf/compiler/java/name_resolver.h> |
38 | |
39 | // Must be last. |
40 | #include <google/protobuf/port_def.inc> |
41 | |
42 | namespace google { |
43 | namespace protobuf { |
44 | namespace compiler { |
45 | namespace java { |
46 | |
47 | namespace { |
48 | |
49 | const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { |
50 | GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); |
51 | const Descriptor* message = descriptor->message_type(); |
52 | GOOGLE_CHECK(message->options().map_entry()); |
53 | return message->map_key(); |
54 | } |
55 | |
56 | const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { |
57 | GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); |
58 | const Descriptor* message = descriptor->message_type(); |
59 | GOOGLE_CHECK(message->options().map_entry()); |
60 | return message->map_value(); |
61 | } |
62 | |
63 | std::string TypeName(const FieldDescriptor* field, |
64 | ClassNameResolver* name_resolver, bool boxed) { |
65 | if (GetJavaType(field) == JAVATYPE_MESSAGE) { |
66 | return name_resolver->GetImmutableClassName(descriptor: field->message_type()); |
67 | } else if (GetJavaType(field) == JAVATYPE_ENUM) { |
68 | return name_resolver->GetImmutableClassName(descriptor: field->enum_type()); |
69 | } else { |
70 | return boxed ? BoxedPrimitiveTypeName(type: GetJavaType(field)) |
71 | : PrimitiveTypeName(type: GetJavaType(field)); |
72 | } |
73 | } |
74 | |
75 | std::string KotlinTypeName(const FieldDescriptor* field, |
76 | ClassNameResolver* name_resolver) { |
77 | if (GetJavaType(field) == JAVATYPE_MESSAGE) { |
78 | return name_resolver->GetImmutableClassName(descriptor: field->message_type()); |
79 | } else if (GetJavaType(field) == JAVATYPE_ENUM) { |
80 | return name_resolver->GetImmutableClassName(descriptor: field->enum_type()); |
81 | } else { |
82 | return KotlinTypeName(type: GetJavaType(field)); |
83 | } |
84 | } |
85 | |
86 | std::string WireType(const FieldDescriptor* field) { |
87 | return "com.google.protobuf.WireFormat.FieldType." + |
88 | std::string(FieldTypeName(field_type: field->type())); |
89 | } |
90 | |
91 | void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, |
92 | int builderBitIndex, const FieldGeneratorInfo* info, |
93 | Context* context, |
94 | std::map<std::string, std::string>* variables) { |
95 | SetCommonFieldVariables(descriptor, info, variables); |
96 | ClassNameResolver* name_resolver = context->GetNameResolver(); |
97 | |
98 | (*variables)["type" ] = |
99 | name_resolver->GetImmutableClassName(descriptor: descriptor->message_type()); |
100 | const FieldDescriptor* key = KeyField(descriptor); |
101 | const FieldDescriptor* value = ValueField(descriptor); |
102 | const JavaType keyJavaType = GetJavaType(field: key); |
103 | const JavaType valueJavaType = GetJavaType(field: value); |
104 | |
105 | std::string pass_through_nullness = "/* nullable */\n" ; |
106 | |
107 | (*variables)["key_type" ] = TypeName(field: key, name_resolver, boxed: false); |
108 | std::string boxed_key_type = TypeName(field: key, name_resolver, boxed: true); |
109 | (*variables)["boxed_key_type" ] = boxed_key_type; |
110 | (*variables)["kt_key_type" ] = KotlinTypeName(field: key, name_resolver); |
111 | (*variables)["kt_value_type" ] = KotlinTypeName(field: value, name_resolver); |
112 | // Used for calling the serialization function. |
113 | (*variables)["short_key_type" ] = |
114 | boxed_key_type.substr(pos: boxed_key_type.rfind(c: '.') + 1); |
115 | (*variables)["key_wire_type" ] = WireType(field: key); |
116 | (*variables)["key_default_value" ] = DefaultValue(field: key, immutable: true, name_resolver); |
117 | (*variables)["key_null_check" ] = |
118 | IsReferenceType(type: keyJavaType) |
119 | ? "if (key == null) { throw new NullPointerException(\"map key\"); }" |
120 | : "" ; |
121 | (*variables)["value_null_check" ] = |
122 | valueJavaType != JAVATYPE_ENUM && IsReferenceType(type: valueJavaType) |
123 | ? "if (value == null) {\n" |
124 | " throw new NullPointerException(\"map value\");\n" |
125 | "}\n" |
126 | : "" ; |
127 | if (valueJavaType == JAVATYPE_ENUM) { |
128 | // We store enums as Integers internally. |
129 | (*variables)["value_type" ] = "int" ; |
130 | (*variables)["boxed_value_type" ] = "java.lang.Integer" ; |
131 | (*variables)["value_wire_type" ] = WireType(field: value); |
132 | (*variables)["value_default_value" ] = |
133 | DefaultValue(field: value, immutable: true, name_resolver) + ".getNumber()" ; |
134 | |
135 | (*variables)["value_enum_type" ] = TypeName(field: value, name_resolver, boxed: false); |
136 | |
137 | (*variables)["value_enum_type_pass_through_nullness" ] = |
138 | pass_through_nullness + (*variables)["value_enum_type" ]; |
139 | |
140 | if (SupportUnknownEnumValue(descriptor: descriptor->file())) { |
141 | // Map unknown values to a special UNRECOGNIZED value if supported. |
142 | (*variables)["unrecognized_value" ] = |
143 | (*variables)["value_enum_type" ] + ".UNRECOGNIZED" ; |
144 | } else { |
145 | // Map unknown values to the default value if we don't have UNRECOGNIZED. |
146 | (*variables)["unrecognized_value" ] = |
147 | DefaultValue(field: value, immutable: true, name_resolver); |
148 | } |
149 | } else { |
150 | (*variables)["value_type" ] = TypeName(field: value, name_resolver, boxed: false); |
151 | |
152 | (*variables)["value_type_pass_through_nullness" ] = |
153 | (IsReferenceType(type: valueJavaType) ? pass_through_nullness : "" ) + |
154 | (*variables)["value_type" ]; |
155 | |
156 | (*variables)["boxed_value_type" ] = TypeName(field: value, name_resolver, boxed: true); |
157 | (*variables)["value_wire_type" ] = WireType(field: value); |
158 | (*variables)["value_default_value" ] = |
159 | DefaultValue(field: value, immutable: true, name_resolver); |
160 | } |
161 | (*variables)["type_parameters" ] = |
162 | (*variables)["boxed_key_type" ] + ", " + (*variables)["boxed_value_type" ]; |
163 | // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported |
164 | // by the proto compiler |
165 | (*variables)["deprecation" ] = |
166 | descriptor->options().deprecated() ? "@java.lang.Deprecated " : "" ; |
167 | (*variables)["kt_deprecation" ] = |
168 | descriptor->options().deprecated() |
169 | ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name" ] + |
170 | " is deprecated\") " |
171 | : "" ; |
172 | (*variables)["on_changed" ] = "onChanged();" ; |
173 | |
174 | // For repeated fields, one bit is used for whether the array is immutable |
175 | // in the parsing constructor. |
176 | (*variables)["get_mutable_bit_parser" ] = |
177 | GenerateGetBitMutableLocal(bitIndex: builderBitIndex); |
178 | (*variables)["set_mutable_bit_parser" ] = |
179 | GenerateSetBitMutableLocal(bitIndex: builderBitIndex); |
180 | |
181 | (*variables)["default_entry" ] = |
182 | (*variables)["capitalized_name" ] + "DefaultEntryHolder.defaultEntry" ; |
183 | (*variables)["map_field_parameter" ] = (*variables)["default_entry" ]; |
184 | (*variables)["descriptor" ] = |
185 | name_resolver->GetImmutableClassName(descriptor: descriptor->file()) + ".internal_" + |
186 | UniqueFileScopeIdentifier(descriptor: descriptor->message_type()) + "_descriptor, " ; |
187 | (*variables)["ver" ] = GeneratedCodeVersionSuffix(); |
188 | } |
189 | |
190 | } // namespace |
191 | |
192 | ImmutableMapFieldGenerator::ImmutableMapFieldGenerator( |
193 | const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, |
194 | Context* context) |
195 | : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { |
196 | SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, |
197 | info: context->GetFieldGeneratorInfo(field: descriptor), context, |
198 | variables: &variables_); |
199 | } |
200 | |
201 | ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {} |
202 | |
203 | int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; } |
204 | |
205 | int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; } |
206 | |
207 | void ImmutableMapFieldGenerator::GenerateInterfaceMembers( |
208 | io::Printer* printer) const { |
209 | WriteFieldDocComment(printer, field: descriptor_); |
210 | printer->Print(variables: variables_, |
211 | text: "$deprecation$int ${$get$capitalized_name$Count$}$();\n" ); |
212 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
213 | WriteFieldDocComment(printer, field: descriptor_); |
214 | printer->Print(variables: variables_, |
215 | text: "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" |
216 | " $key_type$ key);\n" ); |
217 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
218 | if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) { |
219 | printer->Print(variables: variables_, |
220 | text: "/**\n" |
221 | " * Use {@link #get$capitalized_name$Map()} instead.\n" |
222 | " */\n" |
223 | "@java.lang.Deprecated\n" |
224 | "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" |
225 | "${$get$capitalized_name$$}$();\n" ); |
226 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
227 | WriteFieldDocComment(printer, field: descriptor_); |
228 | printer->Print( |
229 | variables: variables_, |
230 | text: "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" |
231 | "${$get$capitalized_name$Map$}$();\n" ); |
232 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
233 | WriteFieldDocComment(printer, field: descriptor_); |
234 | printer->Print(variables: variables_, |
235 | text: "$deprecation$$value_enum_type_pass_through_nullness$ " |
236 | "${$get$capitalized_name$OrDefault$}$(\n" |
237 | " $key_type$ key,\n" |
238 | " $value_enum_type_pass_through_nullness$ " |
239 | " defaultValue);\n" ); |
240 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
241 | WriteFieldDocComment(printer, field: descriptor_); |
242 | printer->Print( |
243 | variables: variables_, |
244 | text: "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" |
245 | " $key_type$ key);\n" ); |
246 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
247 | if (SupportUnknownEnumValue(descriptor: descriptor_->file())) { |
248 | printer->Print( |
249 | variables: variables_, |
250 | text: "/**\n" |
251 | " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" |
252 | " */\n" |
253 | "@java.lang.Deprecated\n" |
254 | "java.util.Map<$type_parameters$>\n" |
255 | "${$get$capitalized_name$Value$}$();\n" ); |
256 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
257 | WriteFieldDocComment(printer, field: descriptor_); |
258 | printer->Print(variables: variables_, |
259 | text: "$deprecation$java.util.Map<$type_parameters$>\n" |
260 | "${$get$capitalized_name$ValueMap$}$();\n" ); |
261 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
262 | WriteFieldDocComment(printer, field: descriptor_); |
263 | printer->Print(variables: variables_, |
264 | text: "$deprecation$\n" |
265 | "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" |
266 | " $key_type$ key,\n" |
267 | " $value_type$ defaultValue);\n" ); |
268 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
269 | WriteFieldDocComment(printer, field: descriptor_); |
270 | printer->Print(variables: variables_, |
271 | text: "$deprecation$\n" |
272 | "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" |
273 | " $key_type$ key);\n" ); |
274 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
275 | } |
276 | } else { |
277 | printer->Print(variables: variables_, |
278 | text: "/**\n" |
279 | " * Use {@link #get$capitalized_name$Map()} instead.\n" |
280 | " */\n" |
281 | "@java.lang.Deprecated\n" |
282 | "java.util.Map<$type_parameters$>\n" |
283 | "${$get$capitalized_name$$}$();\n" ); |
284 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
285 | WriteFieldDocComment(printer, field: descriptor_); |
286 | printer->Print(variables: variables_, |
287 | text: "$deprecation$java.util.Map<$type_parameters$>\n" |
288 | "${$get$capitalized_name$Map$}$();\n" ); |
289 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
290 | WriteFieldDocComment(printer, field: descriptor_); |
291 | printer->Print(variables: variables_, |
292 | text: "$deprecation$\n" |
293 | "$value_type_pass_through_nullness$ " |
294 | "${$get$capitalized_name$OrDefault$}$(\n" |
295 | " $key_type$ key,\n" |
296 | " $value_type_pass_through_nullness$ defaultValue);\n" ); |
297 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
298 | WriteFieldDocComment(printer, field: descriptor_); |
299 | printer->Print(variables: variables_, |
300 | text: "$deprecation$\n" |
301 | "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" |
302 | " $key_type$ key);\n" ); |
303 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
304 | } |
305 | } |
306 | |
307 | void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const { |
308 | printer->Print( |
309 | variables: variables_, |
310 | text: "private static final class $capitalized_name$DefaultEntryHolder {\n" |
311 | " static final com.google.protobuf.MapEntry<\n" |
312 | " $type_parameters$> defaultEntry =\n" |
313 | " com.google.protobuf.MapEntry\n" |
314 | " .<$type_parameters$>newDefaultInstance(\n" |
315 | " $descriptor$\n" |
316 | " $key_wire_type$,\n" |
317 | " $key_default_value$,\n" |
318 | " $value_wire_type$,\n" |
319 | " $value_default_value$);\n" |
320 | "}\n" ); |
321 | printer->Print(variables: variables_, |
322 | text: "private com.google.protobuf.MapField<\n" |
323 | " $type_parameters$> $name$_;\n" |
324 | "private com.google.protobuf.MapField<$type_parameters$>\n" |
325 | "internalGet$capitalized_name$() {\n" |
326 | " if ($name$_ == null) {\n" |
327 | " return com.google.protobuf.MapField.emptyMapField(\n" |
328 | " $map_field_parameter$);\n" |
329 | " }\n" |
330 | " return $name$_;\n" |
331 | "}\n" ); |
332 | if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) { |
333 | printer->Print( |
334 | variables: variables_, |
335 | text: "private static final\n" |
336 | "com.google.protobuf.Internal.MapAdapter.Converter<\n" |
337 | " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n" |
338 | " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n" |
339 | " $value_enum_type$.internalGetValueMap(),\n" |
340 | " $unrecognized_value$);\n" ); |
341 | printer->Print( |
342 | variables: variables_, |
343 | text: "private static final java.util.Map<$boxed_key_type$, " |
344 | "$value_enum_type$>\n" |
345 | "internalGetAdapted$capitalized_name$Map(\n" |
346 | " java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n" |
347 | " return new com.google.protobuf.Internal.MapAdapter<\n" |
348 | " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" |
349 | " map, $name$ValueConverter);\n" |
350 | "}\n" ); |
351 | } |
352 | GenerateMapGetters(printer); |
353 | } |
354 | |
355 | void ImmutableMapFieldGenerator::GenerateBuilderMembers( |
356 | io::Printer* printer) const { |
357 | printer->Print(variables: variables_, |
358 | text: "private com.google.protobuf.MapField<\n" |
359 | " $type_parameters$> $name$_;\n" |
360 | "private com.google.protobuf.MapField<$type_parameters$>\n" |
361 | "internalGet$capitalized_name$() {\n" |
362 | " if ($name$_ == null) {\n" |
363 | " return com.google.protobuf.MapField.emptyMapField(\n" |
364 | " $map_field_parameter$);\n" |
365 | " }\n" |
366 | " return $name$_;\n" |
367 | "}\n" |
368 | "private com.google.protobuf.MapField<$type_parameters$>\n" |
369 | "internalGetMutable$capitalized_name$() {\n" |
370 | " $on_changed$;\n" |
371 | " if ($name$_ == null) {\n" |
372 | " $name$_ = com.google.protobuf.MapField.newMapField(\n" |
373 | " $map_field_parameter$);\n" |
374 | " }\n" |
375 | " if (!$name$_.isMutable()) {\n" |
376 | " $name$_ = $name$_.copy();\n" |
377 | " }\n" |
378 | " return $name$_;\n" |
379 | "}\n" ); |
380 | GenerateMapGetters(printer); |
381 | printer->Print(variables: variables_, |
382 | text: "$deprecation$\n" |
383 | "public Builder ${$clear$capitalized_name$$}$() {\n" |
384 | " internalGetMutable$capitalized_name$().getMutableMap()\n" |
385 | " .clear();\n" |
386 | " return this;\n" |
387 | "}\n" ); |
388 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
389 | WriteFieldDocComment(printer, field: descriptor_); |
390 | printer->Print(variables: variables_, |
391 | text: "$deprecation$\n" |
392 | "public Builder ${$remove$capitalized_name$$}$(\n" |
393 | " $key_type$ key) {\n" |
394 | " $key_null_check$\n" |
395 | " internalGetMutable$capitalized_name$().getMutableMap()\n" |
396 | " .remove(key);\n" |
397 | " return this;\n" |
398 | "}\n" ); |
399 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
400 | if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) { |
401 | printer->Print( |
402 | variables: variables_, |
403 | text: "/**\n" |
404 | " * Use alternate mutation accessors instead.\n" |
405 | " */\n" |
406 | "@java.lang.Deprecated\n" |
407 | "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" |
408 | "${$getMutable$capitalized_name$$}$() {\n" |
409 | " return internalGetAdapted$capitalized_name$Map(\n" |
410 | " internalGetMutable$capitalized_name$().getMutableMap());\n" |
411 | "}\n" ); |
412 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
413 | WriteFieldDocComment(printer, field: descriptor_); |
414 | printer->Print(variables: variables_, |
415 | text: "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" |
416 | " $key_type$ key,\n" |
417 | " $value_enum_type$ value) {\n" |
418 | " $key_null_check$\n" |
419 | " $value_null_check$\n" |
420 | " internalGetMutable$capitalized_name$().getMutableMap()\n" |
421 | " .put(key, $name$ValueConverter.doBackward(value));\n" |
422 | " return this;\n" |
423 | "}\n" ); |
424 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
425 | WriteFieldDocComment(printer, field: descriptor_); |
426 | printer->Print( |
427 | variables: variables_, |
428 | text: "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" |
429 | " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" |
430 | " internalGetAdapted$capitalized_name$Map(\n" |
431 | " internalGetMutable$capitalized_name$().getMutableMap())\n" |
432 | " .putAll(values);\n" |
433 | " return this;\n" |
434 | "}\n" ); |
435 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
436 | if (SupportUnknownEnumValue(descriptor: descriptor_->file())) { |
437 | printer->Print( |
438 | variables: variables_, |
439 | text: "/**\n" |
440 | " * Use alternate mutation accessors instead.\n" |
441 | " */\n" |
442 | "@java.lang.Deprecated\n" |
443 | "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" |
444 | "${$getMutable$capitalized_name$Value$}$() {\n" |
445 | " return internalGetMutable$capitalized_name$().getMutableMap();\n" |
446 | "}\n" ); |
447 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
448 | WriteFieldDocComment(printer, field: descriptor_); |
449 | printer->Print( |
450 | variables: variables_, |
451 | text: "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" |
452 | " $key_type$ key,\n" |
453 | " $value_type$ value) {\n" |
454 | " $key_null_check$\n" |
455 | " $value_null_check$\n" |
456 | " internalGetMutable$capitalized_name$().getMutableMap()\n" |
457 | " .put(key, value);\n" |
458 | " return this;\n" |
459 | "}\n" ); |
460 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
461 | WriteFieldDocComment(printer, field: descriptor_); |
462 | printer->Print( |
463 | variables: variables_, |
464 | text: "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" |
465 | " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" |
466 | " internalGetMutable$capitalized_name$().getMutableMap()\n" |
467 | " .putAll(values);\n" |
468 | " return this;\n" |
469 | "}\n" ); |
470 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
471 | } |
472 | } else { |
473 | printer->Print( |
474 | variables: variables_, |
475 | text: "/**\n" |
476 | " * Use alternate mutation accessors instead.\n" |
477 | " */\n" |
478 | "@java.lang.Deprecated\n" |
479 | "public java.util.Map<$type_parameters$>\n" |
480 | "${$getMutable$capitalized_name$$}$() {\n" |
481 | " return internalGetMutable$capitalized_name$().getMutableMap();\n" |
482 | "}\n" ); |
483 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
484 | WriteFieldDocComment(printer, field: descriptor_); |
485 | printer->Print(variables: variables_, |
486 | text: "$deprecation$" |
487 | "public Builder ${$put$capitalized_name$$}$(\n" |
488 | " $key_type$ key,\n" |
489 | " $value_type$ value) {\n" |
490 | " $key_null_check$\n" |
491 | " $value_null_check$\n" |
492 | " internalGetMutable$capitalized_name$().getMutableMap()\n" |
493 | " .put(key, value);\n" |
494 | " return this;\n" |
495 | "}\n" ); |
496 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
497 | WriteFieldDocComment(printer, field: descriptor_); |
498 | printer->Print(variables: variables_, |
499 | text: "$deprecation$\n" |
500 | "public Builder ${$putAll$capitalized_name$$}$(\n" |
501 | " java.util.Map<$type_parameters$> values) {\n" |
502 | " internalGetMutable$capitalized_name$().getMutableMap()\n" |
503 | " .putAll(values);\n" |
504 | " return this;\n" |
505 | "}\n" ); |
506 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
507 | } |
508 | } |
509 | |
510 | void ImmutableMapFieldGenerator::GenerateMapGetters( |
511 | io::Printer* printer) const { |
512 | printer->Print(variables: variables_, |
513 | text: "$deprecation$\n" |
514 | "public int ${$get$capitalized_name$Count$}$() {\n" |
515 | " return internalGet$capitalized_name$().getMap().size();\n" |
516 | "}\n" ); |
517 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
518 | WriteFieldDocComment(printer, field: descriptor_); |
519 | printer->Print( |
520 | variables: variables_, |
521 | text: "$deprecation$\n" |
522 | "@java.lang.Override\n" |
523 | "public boolean ${$contains$capitalized_name$$}$(\n" |
524 | " $key_type$ key) {\n" |
525 | " $key_null_check$\n" |
526 | " return internalGet$capitalized_name$().getMap().containsKey(key);\n" |
527 | "}\n" ); |
528 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
529 | if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) { |
530 | printer->Print(variables: variables_, |
531 | text: "/**\n" |
532 | " * Use {@link #get$capitalized_name$Map()} instead.\n" |
533 | " */\n" |
534 | "@java.lang.Override\n" |
535 | "@java.lang.Deprecated\n" |
536 | "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" |
537 | "${$get$capitalized_name$$}$() {\n" |
538 | " return get$capitalized_name$Map();\n" |
539 | "}\n" ); |
540 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
541 | WriteFieldDocComment(printer, field: descriptor_); |
542 | printer->Print(variables: variables_, |
543 | text: "@java.lang.Override\n" |
544 | "$deprecation$\n" |
545 | "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" |
546 | "${$get$capitalized_name$Map$}$() {\n" |
547 | " return internalGetAdapted$capitalized_name$Map(\n" |
548 | " internalGet$capitalized_name$().getMap());" |
549 | "}\n" ); |
550 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
551 | WriteFieldDocComment(printer, field: descriptor_); |
552 | printer->Print( |
553 | variables: variables_, |
554 | text: "@java.lang.Override\n" |
555 | "$deprecation$\n" |
556 | "public $value_enum_type_pass_through_nullness$ " |
557 | "${$get$capitalized_name$OrDefault$}$(\n" |
558 | " $key_type$ key,\n" |
559 | " $value_enum_type_pass_through_nullness$ defaultValue) {\n" |
560 | " $key_null_check$\n" |
561 | " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" |
562 | " internalGet$capitalized_name$().getMap();\n" |
563 | " return map.containsKey(key)\n" |
564 | " ? $name$ValueConverter.doForward(map.get(key))\n" |
565 | " : defaultValue;\n" |
566 | "}\n" ); |
567 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
568 | WriteFieldDocComment(printer, field: descriptor_); |
569 | printer->Print( |
570 | variables: variables_, |
571 | text: "@java.lang.Override\n" |
572 | "$deprecation$\n" |
573 | "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" |
574 | " $key_type$ key) {\n" |
575 | " $key_null_check$\n" |
576 | " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" |
577 | " internalGet$capitalized_name$().getMap();\n" |
578 | " if (!map.containsKey(key)) {\n" |
579 | " throw new java.lang.IllegalArgumentException();\n" |
580 | " }\n" |
581 | " return $name$ValueConverter.doForward(map.get(key));\n" |
582 | "}\n" ); |
583 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
584 | if (SupportUnknownEnumValue(descriptor: descriptor_->file())) { |
585 | printer->Print( |
586 | variables: variables_, |
587 | text: "/**\n" |
588 | " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" |
589 | " */\n" |
590 | "@java.lang.Override\n" |
591 | "@java.lang.Deprecated\n" |
592 | "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" |
593 | "${$get$capitalized_name$Value$}$() {\n" |
594 | " return get$capitalized_name$ValueMap();\n" |
595 | "}\n" ); |
596 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
597 | WriteFieldDocComment(printer, field: descriptor_); |
598 | printer->Print( |
599 | variables: variables_, |
600 | text: "@java.lang.Override\n" |
601 | "$deprecation$\n" |
602 | "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" |
603 | "${$get$capitalized_name$ValueMap$}$() {\n" |
604 | " return internalGet$capitalized_name$().getMap();\n" |
605 | "}\n" ); |
606 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
607 | WriteFieldDocComment(printer, field: descriptor_); |
608 | printer->Print( |
609 | variables: variables_, |
610 | text: "@java.lang.Override\n" |
611 | "$deprecation$\n" |
612 | "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" |
613 | " $key_type$ key,\n" |
614 | " $value_type$ defaultValue) {\n" |
615 | " $key_null_check$\n" |
616 | " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" |
617 | " internalGet$capitalized_name$().getMap();\n" |
618 | " return map.containsKey(key) ? map.get(key) : defaultValue;\n" |
619 | "}\n" ); |
620 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
621 | WriteFieldDocComment(printer, field: descriptor_); |
622 | printer->Print( |
623 | variables: variables_, |
624 | text: "@java.lang.Override\n" |
625 | "$deprecation$\n" |
626 | "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" |
627 | " $key_type$ key) {\n" |
628 | " $key_null_check$\n" |
629 | " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" |
630 | " internalGet$capitalized_name$().getMap();\n" |
631 | " if (!map.containsKey(key)) {\n" |
632 | " throw new java.lang.IllegalArgumentException();\n" |
633 | " }\n" |
634 | " return map.get(key);\n" |
635 | "}\n" ); |
636 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
637 | } |
638 | } else { |
639 | printer->Print(variables: variables_, |
640 | text: "/**\n" |
641 | " * Use {@link #get$capitalized_name$Map()} instead.\n" |
642 | " */\n" |
643 | "@java.lang.Override\n" |
644 | "@java.lang.Deprecated\n" |
645 | "public java.util.Map<$type_parameters$> " |
646 | "${$get$capitalized_name$$}$() {\n" |
647 | " return get$capitalized_name$Map();\n" |
648 | "}\n" ); |
649 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
650 | WriteFieldDocComment(printer, field: descriptor_); |
651 | printer->Print(variables: variables_, |
652 | text: "@java.lang.Override\n" |
653 | "$deprecation$\n" |
654 | "public java.util.Map<$type_parameters$> " |
655 | "${$get$capitalized_name$Map$}$() {\n" |
656 | " return internalGet$capitalized_name$().getMap();\n" |
657 | "}\n" ); |
658 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
659 | WriteFieldDocComment(printer, field: descriptor_); |
660 | printer->Print( |
661 | variables: variables_, |
662 | text: "@java.lang.Override\n" |
663 | "$deprecation$\n" |
664 | "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" |
665 | " $key_type$ key,\n" |
666 | " $value_type$ defaultValue) {\n" |
667 | " $key_null_check$\n" |
668 | " java.util.Map<$type_parameters$> map =\n" |
669 | " internalGet$capitalized_name$().getMap();\n" |
670 | " return map.containsKey(key) ? map.get(key) : defaultValue;\n" |
671 | "}\n" ); |
672 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
673 | WriteFieldDocComment(printer, field: descriptor_); |
674 | printer->Print(variables: variables_, |
675 | text: "@java.lang.Override\n" |
676 | "$deprecation$\n" |
677 | "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" |
678 | " $key_type$ key) {\n" |
679 | " $key_null_check$\n" |
680 | " java.util.Map<$type_parameters$> map =\n" |
681 | " internalGet$capitalized_name$().getMap();\n" |
682 | " if (!map.containsKey(key)) {\n" |
683 | " throw new java.lang.IllegalArgumentException();\n" |
684 | " }\n" |
685 | " return map.get(key);\n" |
686 | "}\n" ); |
687 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
688 | } |
689 | } |
690 | |
691 | void ImmutableMapFieldGenerator::GenerateKotlinDslMembers( |
692 | io::Printer* printer) const { |
693 | printer->Print( |
694 | variables: variables_, |
695 | text: "/**\n" |
696 | " * An uninstantiable, behaviorless type to represent the field in\n" |
697 | " * generics.\n" |
698 | " */\n" |
699 | "@kotlin.OptIn" |
700 | "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" |
701 | "class ${$$kt_capitalized_name$Proxy$}$ private constructor()" |
702 | " : com.google.protobuf.kotlin.DslProxy()\n" ); |
703 | |
704 | WriteFieldDocComment(printer, field: descriptor_); |
705 | printer->Print( |
706 | variables: variables_, |
707 | text: "$kt_deprecation$ val $kt_name$: " |
708 | "com.google.protobuf.kotlin.DslMap" |
709 | "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" |
710 | " @kotlin.jvm.JvmSynthetic\n" |
711 | " @JvmName(\"get$kt_capitalized_name$Map\")\n" |
712 | " get() = com.google.protobuf.kotlin.DslMap(\n" |
713 | " $kt_dsl_builder$.${$get$capitalized_name$Map$}$()\n" |
714 | " )\n" ); |
715 | |
716 | WriteFieldDocComment(printer, field: descriptor_); |
717 | printer->Print( |
718 | variables: variables_, |
719 | text: "@JvmName(\"put$kt_capitalized_name$\")\n" |
720 | "fun com.google.protobuf.kotlin.DslMap" |
721 | "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" |
722 | " .put(key: $kt_key_type$, value: $kt_value_type$) {\n" |
723 | " $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n" |
724 | " }\n" ); |
725 | |
726 | WriteFieldDocComment(printer, field: descriptor_); |
727 | printer->Print( |
728 | variables: variables_, |
729 | text: "@kotlin.jvm.JvmSynthetic\n" |
730 | "@JvmName(\"set$kt_capitalized_name$\")\n" |
731 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
732 | "inline operator fun com.google.protobuf.kotlin.DslMap" |
733 | "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" |
734 | " .set(key: $kt_key_type$, value: $kt_value_type$) {\n" |
735 | " put(key, value)\n" |
736 | " }\n" ); |
737 | |
738 | WriteFieldDocComment(printer, field: descriptor_); |
739 | printer->Print( |
740 | variables: variables_, |
741 | text: "@kotlin.jvm.JvmSynthetic\n" |
742 | "@JvmName(\"remove$kt_capitalized_name$\")\n" |
743 | "fun com.google.protobuf.kotlin.DslMap" |
744 | "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" |
745 | " .remove(key: $kt_key_type$) {\n" |
746 | " $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n" |
747 | " }\n" ); |
748 | |
749 | WriteFieldDocComment(printer, field: descriptor_); |
750 | printer->Print( |
751 | variables: variables_, |
752 | text: "@kotlin.jvm.JvmSynthetic\n" |
753 | "@JvmName(\"putAll$kt_capitalized_name$\")\n" |
754 | "fun com.google.protobuf.kotlin.DslMap" |
755 | "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" |
756 | " .putAll(map: kotlin.collections.Map<$kt_key_type$, $kt_value_type$>) " |
757 | "{\n" |
758 | " $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n" |
759 | " }\n" ); |
760 | |
761 | WriteFieldDocComment(printer, field: descriptor_); |
762 | printer->Print( |
763 | variables: variables_, |
764 | text: "@kotlin.jvm.JvmSynthetic\n" |
765 | "@JvmName(\"clear$kt_capitalized_name$\")\n" |
766 | "fun com.google.protobuf.kotlin.DslMap" |
767 | "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" |
768 | " .clear() {\n" |
769 | " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" |
770 | " }\n" ); |
771 | } |
772 | |
773 | void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode( |
774 | io::Printer* printer) const { |
775 | // Nothing to initialize. |
776 | } |
777 | |
778 | void ImmutableMapFieldGenerator::GenerateInitializationCode( |
779 | io::Printer* printer) const { |
780 | // Nothing to initialize. |
781 | } |
782 | |
783 | void ImmutableMapFieldGenerator::GenerateBuilderClearCode( |
784 | io::Printer* printer) const { |
785 | printer->Print(variables: variables_, |
786 | text: "internalGetMutable$capitalized_name$().clear();\n" ); |
787 | } |
788 | |
789 | void ImmutableMapFieldGenerator::GenerateMergingCode( |
790 | io::Printer* printer) const { |
791 | printer->Print(variables: variables_, |
792 | text: "internalGetMutable$capitalized_name$().mergeFrom(\n" |
793 | " other.internalGet$capitalized_name$());\n" ); |
794 | } |
795 | |
796 | void ImmutableMapFieldGenerator::GenerateBuildingCode( |
797 | io::Printer* printer) const { |
798 | printer->Print(variables: variables_, |
799 | text: "result.$name$_ = internalGet$capitalized_name$();\n" |
800 | "result.$name$_.makeImmutable();\n" ); |
801 | } |
802 | |
803 | void ImmutableMapFieldGenerator::GenerateParsingCode( |
804 | io::Printer* printer) const { |
805 | printer->Print(variables: variables_, |
806 | text: "if (!$get_mutable_bit_parser$) {\n" |
807 | " $name$_ = com.google.protobuf.MapField.newMapField(\n" |
808 | " $map_field_parameter$);\n" |
809 | " $set_mutable_bit_parser$;\n" |
810 | "}\n" ); |
811 | if (!SupportUnknownEnumValue(descriptor: descriptor_->file()) && |
812 | GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) { |
813 | printer->Print( |
814 | variables: variables_, |
815 | text: "com.google.protobuf.ByteString bytes = input.readBytes();\n" |
816 | "com.google.protobuf.MapEntry<$type_parameters$>\n" |
817 | "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n" ); |
818 | printer->Print( |
819 | variables: variables_, |
820 | text: "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n" |
821 | " unknownFields.mergeLengthDelimitedField($number$, bytes);\n" |
822 | "} else {\n" |
823 | " $name$_.getMutableMap().put(\n" |
824 | " $name$__.getKey(), $name$__.getValue());\n" |
825 | "}\n" ); |
826 | } else { |
827 | printer->Print( |
828 | variables: variables_, |
829 | text: "com.google.protobuf.MapEntry<$type_parameters$>\n" |
830 | "$name$__ = input.readMessage(\n" |
831 | " $default_entry$.getParserForType(), extensionRegistry);\n" |
832 | "$name$_.getMutableMap().put(\n" |
833 | " $name$__.getKey(), $name$__.getValue());\n" ); |
834 | } |
835 | } |
836 | |
837 | void ImmutableMapFieldGenerator::GenerateParsingDoneCode( |
838 | io::Printer* printer) const { |
839 | // Nothing to do here. |
840 | } |
841 | |
842 | void ImmutableMapFieldGenerator::GenerateSerializationCode( |
843 | io::Printer* printer) const { |
844 | printer->Print(variables: variables_, |
845 | text: "com.google.protobuf.GeneratedMessage$ver$\n" |
846 | " .serialize$short_key_type$MapTo(\n" |
847 | " output,\n" |
848 | " internalGet$capitalized_name$(),\n" |
849 | " $default_entry$,\n" |
850 | " $number$);\n" ); |
851 | } |
852 | |
853 | void ImmutableMapFieldGenerator::GenerateSerializedSizeCode( |
854 | io::Printer* printer) const { |
855 | printer->Print( |
856 | variables: variables_, |
857 | text: "for (java.util.Map.Entry<$type_parameters$> entry\n" |
858 | " : internalGet$capitalized_name$().getMap().entrySet()) {\n" |
859 | " com.google.protobuf.MapEntry<$type_parameters$>\n" |
860 | " $name$__ = $default_entry$.newBuilderForType()\n" |
861 | " .setKey(entry.getKey())\n" |
862 | " .setValue(entry.getValue())\n" |
863 | " .build();\n" |
864 | " size += com.google.protobuf.CodedOutputStream\n" |
865 | " .computeMessageSize($number$, $name$__);\n" |
866 | "}\n" ); |
867 | } |
868 | |
869 | void ImmutableMapFieldGenerator::GenerateEqualsCode( |
870 | io::Printer* printer) const { |
871 | printer->Print(variables: variables_, |
872 | text: "if (!internalGet$capitalized_name$().equals(\n" |
873 | " other.internalGet$capitalized_name$())) return false;\n" ); |
874 | } |
875 | |
876 | void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const { |
877 | printer->Print( |
878 | variables: variables_, |
879 | text: "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n" |
880 | " hash = (37 * hash) + $constant_name$;\n" |
881 | " hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n" |
882 | "}\n" ); |
883 | } |
884 | |
885 | std::string ImmutableMapFieldGenerator::GetBoxedType() const { |
886 | return name_resolver_->GetImmutableClassName(descriptor: descriptor_->message_type()); |
887 | } |
888 | |
889 | } // namespace java |
890 | } // namespace compiler |
891 | } // namespace protobuf |
892 | } // namespace google |
893 | |
894 | #include <google/protobuf/port_undef.inc> |
895 | |