1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 #include "google/protobuf/compiler/java/full/map_field.h"
9
10 #include <string>
11
12 #include "absl/strings/str_cat.h"
13 #include "absl/strings/str_join.h"
14 #include "google/protobuf/compiler/java/context.h"
15 #include "google/protobuf/compiler/java/doc_comment.h"
16 #include "google/protobuf/compiler/java/field_common.h"
17 #include "google/protobuf/compiler/java/helpers.h"
18 #include "google/protobuf/compiler/java/internal_helpers.h"
19 #include "google/protobuf/compiler/java/name_resolver.h"
20 #include "google/protobuf/io/printer.h"
21
22 // Must be last.
23 #include "google/protobuf/port_def.inc"
24
25 namespace google {
26 namespace protobuf {
27 namespace compiler {
28 namespace java {
29
30 namespace {
31 using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
32
TypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver,bool boxed)33 std::string TypeName(const FieldDescriptor* field,
34 ClassNameResolver* name_resolver, bool boxed) {
35 if (GetJavaType(field) == JAVATYPE_MESSAGE) {
36 return name_resolver->GetImmutableClassName(field->message_type());
37 } else if (GetJavaType(field) == JAVATYPE_ENUM) {
38 return name_resolver->GetImmutableClassName(field->enum_type());
39 } else {
40 return std::string(boxed ? BoxedPrimitiveTypeName(GetJavaType(field))
41 : PrimitiveTypeName(GetJavaType(field)));
42 }
43 }
44
KotlinTypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver)45 std::string KotlinTypeName(const FieldDescriptor* field,
46 ClassNameResolver* name_resolver) {
47 if (GetJavaType(field) == JAVATYPE_MESSAGE) {
48 return name_resolver->GetImmutableClassName(field->message_type());
49 } else if (GetJavaType(field) == JAVATYPE_ENUM) {
50 return name_resolver->GetImmutableClassName(field->enum_type());
51 } else {
52 return std::string(KotlinTypeName(GetJavaType(field)));
53 }
54 }
55
WireType(const FieldDescriptor * field)56 std::string WireType(const FieldDescriptor* field) {
57 return absl::StrCat("com.google.protobuf.WireFormat.FieldType.",
58 FieldTypeName(field->type()));
59 }
60
61 } // namespace
62
ImmutableMapFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)63 ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
64 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
65 Context* context)
66 : descriptor_(descriptor),
67 message_bit_index_(messageBitIndex),
68 builder_bit_index_(builderBitIndex),
69 name_resolver_(context->GetNameResolver()),
70 context_(context) {
71 SetMessageVariables(context->GetFieldGeneratorInfo(descriptor));
72 }
73
SetMessageVariables(const FieldGeneratorInfo * info)74 void ImmutableMapFieldGenerator::SetMessageVariables(
75 const FieldGeneratorInfo* info) {
76 SetCommonFieldVariables(descriptor_, info, &variables_);
77 ClassNameResolver* name_resolver = context_->GetNameResolver();
78
79 variables_["type"] =
80 name_resolver->GetImmutableClassName(descriptor_->message_type());
81 const FieldDescriptor* key = MapKeyField(descriptor_);
82 const FieldDescriptor* value = MapValueField(descriptor_);
83 const JavaType keyJavaType = GetJavaType(key);
84 const JavaType valueJavaType = GetJavaType(value);
85
86 // The code that generates the open-source version appears not to understand
87 // #else, so we have an #ifndef instead.
88 std::string pass_through_nullness =
89 context_->options().opensource_runtime
90 ? "/* nullable */\n"
91 : "@com.google.protobuf.Internal.ProtoPassThroughNullness ";
92
93 variables_["key_type"] = TypeName(key, name_resolver, false);
94 std::string boxed_key_type = TypeName(key, name_resolver, true);
95 variables_["boxed_key_type"] = boxed_key_type;
96 variables_["kt_key_type"] = KotlinTypeName(key, name_resolver);
97 variables_["kt_value_type"] = KotlinTypeName(value, name_resolver);
98 // Used for calling the serialization function.
99 variables_["short_key_type"] =
100 boxed_key_type.substr(boxed_key_type.rfind('.') + 1);
101 variables_["key_wire_type"] = WireType(key);
102 variables_["key_default_value"] =
103 DefaultValue(key, true, name_resolver, context_->options());
104 variables_["key_null_check"] =
105 IsReferenceType(keyJavaType)
106 ? "if (key == null) { throw new NullPointerException(\"map key\"); }"
107 : "";
108 variables_["value_null_check"] =
109 valueJavaType != JAVATYPE_ENUM && IsReferenceType(valueJavaType)
110 ? "if (value == null) { "
111 "throw new NullPointerException(\"map value\"); }"
112 : "";
113 if (valueJavaType == JAVATYPE_ENUM) {
114 // We store enums as Integers internally.
115 variables_["value_type"] = "int";
116 variables_.insert(
117 {"value_type_pass_through_nullness", variables_["value_type"]});
118 variables_["boxed_value_type"] = "java.lang.Integer";
119 variables_["value_wire_type"] = WireType(value);
120 variables_["value_default_value"] =
121 DefaultValue(value, true, name_resolver, context_->options()) +
122 ".getNumber()";
123
124 variables_["value_enum_type"] = TypeName(value, name_resolver, false);
125
126 variables_.insert(
127 {"value_enum_type_pass_through_nullness",
128 absl::StrCat(pass_through_nullness, variables_["value_enum_type"])});
129
130 if (SupportUnknownEnumValue(value)) {
131 // Map unknown values to a special UNRECOGNIZED value if supported.
132 variables_.insert(
133 {"unrecognized_value",
134 absl::StrCat(variables_["value_enum_type"], ".UNRECOGNIZED")});
135 } else {
136 // Map unknown values to the default value if we don't have UNRECOGNIZED.
137 variables_["unrecognized_value"] =
138 DefaultValue(value, true, name_resolver, context_->options());
139 }
140 } else {
141 variables_["value_type"] = TypeName(value, name_resolver, false);
142
143 variables_.insert(
144 {"value_type_pass_through_nullness",
145 absl::StrCat(
146 (IsReferenceType(valueJavaType) ? pass_through_nullness : ""),
147 variables_["value_type"])});
148
149 variables_["boxed_value_type"] = TypeName(value, name_resolver, true);
150 variables_["value_wire_type"] = WireType(value);
151 variables_["value_default_value"] =
152 DefaultValue(value, true, name_resolver, context_->options());
153 }
154
155 variables_.insert(
156 {"type_parameters", absl::StrCat(variables_["boxed_key_type"], ", ",
157 variables_["boxed_value_type"])});
158
159 if (valueJavaType == JAVATYPE_MESSAGE) {
160 variables_["value_interface_type"] =
161 absl::StrCat(variables_["boxed_value_type"], "OrBuilder");
162 variables_["value_builder_type"] =
163 absl::StrCat(variables_["boxed_value_type"], ".Builder");
164 variables_["builder_type_parameters"] = absl::StrJoin(
165 {variables_["boxed_key_type"], variables_["value_interface_type"],
166 variables_["boxed_value_type"], variables_["value_builder_type"]},
167 ", ");
168 }
169 // TODO: Add @deprecated javadoc when generating javadoc is supported
170 // by the proto compiler
171 variables_["deprecation"] =
172 descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
173 variables_.insert(
174 {"kt_deprecation",
175 descriptor_->options().deprecated()
176 ? absl::StrCat("@kotlin.Deprecated(message = \"Field ",
177 variables_["name"], " is deprecated\") ")
178 : ""});
179 variables_["on_changed"] = "onChanged();";
180
181 variables_.insert(
182 {"default_entry", absl::StrCat(variables_["capitalized_name"],
183 "DefaultEntryHolder.defaultEntry")});
184 variables_.insert({"map_field_parameter", variables_["default_entry"]});
185 variables_["descriptor"] = absl::StrCat(
186 name_resolver->GetImmutableClassName(descriptor_->file()), ".internal_",
187 UniqueFileScopeIdentifier(descriptor_->message_type()), "_descriptor, ");
188 variables_["get_has_field_bit_builder"] = GenerateGetBit(builder_bit_index_);
189 variables_["get_has_field_bit_from_local"] =
190 GenerateGetBitFromLocal(builder_bit_index_);
191 variables_["set_has_field_bit_builder"] =
192 absl::StrCat(GenerateSetBit(builder_bit_index_), ";");
193 variables_["clear_has_field_bit_builder"] =
194 absl::StrCat(GenerateClearBit(builder_bit_index_), ";");
195 }
196
GetMessageBitIndex() const197 int ImmutableMapFieldGenerator::GetMessageBitIndex() const {
198 return message_bit_index_;
199 }
200
GetBuilderBitIndex() const201 int ImmutableMapFieldGenerator::GetBuilderBitIndex() const {
202 return builder_bit_index_;
203 }
204
GetNumBitsForMessage() const205 int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; }
206
GetNumBitsForBuilder() const207 int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; }
208
GenerateInterfaceMembers(io::Printer * printer) const209 void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
210 io::Printer* printer) const {
211 WriteFieldDocComment(printer, descriptor_, context_->options());
212 printer->Print(variables_,
213 "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
214 printer->Annotate("{", "}", descriptor_);
215 WriteFieldDocComment(printer, descriptor_, context_->options());
216 printer->Print(variables_,
217 "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
218 " $key_type$ key);\n");
219 printer->Annotate("{", "}", descriptor_);
220
221 const FieldDescriptor* value = MapValueField(descriptor_);
222 if (GetJavaType(value) == JAVATYPE_ENUM) {
223 if (context_->options().opensource_runtime) {
224 printer->Print(variables_,
225 "/**\n"
226 " * Use {@link #get$capitalized_name$Map()} instead.\n"
227 " */\n"
228 "@java.lang.Deprecated\n"
229 "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
230 "${$get$capitalized_name$$}$();\n");
231 printer->Annotate("{", "}", descriptor_);
232 }
233 WriteFieldDocComment(printer, descriptor_, context_->options());
234 printer->Print(
235 variables_,
236 "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
237 "${$get$capitalized_name$Map$}$();\n");
238 printer->Annotate("{", "}", descriptor_);
239 WriteFieldDocComment(printer, descriptor_, context_->options());
240 printer->Print(variables_,
241 "$deprecation$$value_enum_type_pass_through_nullness$ "
242 "${$get$capitalized_name$OrDefault$}$(\n"
243 " $key_type$ key,\n"
244 " $value_enum_type_pass_through_nullness$ "
245 " defaultValue);\n");
246 printer->Annotate("{", "}", descriptor_);
247 WriteFieldDocComment(printer, descriptor_, context_->options());
248 printer->Print(
249 variables_,
250 "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
251 " $key_type$ key);\n");
252 printer->Annotate("{", "}", descriptor_);
253 if (SupportUnknownEnumValue(value)) {
254 printer->Print(
255 variables_,
256 "/**\n"
257 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
258 " */\n"
259 "@java.lang.Deprecated\n"
260 "java.util.Map<$type_parameters$>\n"
261 "${$get$capitalized_name$Value$}$();\n");
262 printer->Annotate("{", "}", descriptor_);
263 WriteFieldDocComment(printer, descriptor_, context_->options());
264 printer->Print(variables_,
265 "$deprecation$java.util.Map<$type_parameters$>\n"
266 "${$get$capitalized_name$ValueMap$}$();\n");
267 printer->Annotate("{", "}", descriptor_);
268 WriteFieldDocComment(printer, descriptor_, context_->options());
269 printer->Print(variables_,
270 "$deprecation$$value_type_pass_through_nullness$ "
271 "${$get$capitalized_name$ValueOrDefault$}$(\n"
272 " $key_type$ key,\n"
273 " $value_type_pass_through_nullness$ defaultValue);\n");
274 printer->Annotate("{", "}", descriptor_);
275 WriteFieldDocComment(printer, descriptor_, context_->options());
276 printer->Print(
277 variables_,
278 "$deprecation$$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
279 " $key_type$ key);\n");
280 printer->Annotate("{", "}", descriptor_);
281 }
282 } else {
283 if (context_->options().opensource_runtime) {
284 printer->Print(variables_,
285 "/**\n"
286 " * Use {@link #get$capitalized_name$Map()} instead.\n"
287 " */\n"
288 "@java.lang.Deprecated\n"
289 "java.util.Map<$type_parameters$>\n"
290 "${$get$capitalized_name$$}$();\n");
291 printer->Annotate("{", "}", descriptor_);
292 }
293 WriteFieldDocComment(printer, descriptor_, context_->options());
294 printer->Print(variables_,
295 "$deprecation$java.util.Map<$type_parameters$>\n"
296 "${$get$capitalized_name$Map$}$();\n");
297 printer->Annotate("{", "}", descriptor_);
298 WriteFieldDocComment(printer, descriptor_, context_->options());
299 printer->Print(variables_,
300 "$deprecation$$value_type_pass_through_nullness$ "
301 "${$get$capitalized_name$OrDefault$}$(\n"
302 " $key_type$ key,\n"
303 " $value_type_pass_through_nullness$ defaultValue);\n");
304 printer->Annotate("{", "}", descriptor_);
305 WriteFieldDocComment(printer, descriptor_, context_->options());
306 printer->Print(
307 variables_,
308 "$deprecation$$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
309 " $key_type$ key);\n");
310 printer->Annotate("{", "}", descriptor_);
311 }
312 }
313
GenerateMembers(io::Printer * printer) const314 void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
315 printer->Print(
316 variables_,
317 "private static final class $capitalized_name$DefaultEntryHolder {\n"
318 " static final com.google.protobuf.MapEntry<\n"
319 " $type_parameters$> defaultEntry =\n"
320 " com.google.protobuf.MapEntry\n"
321 " .<$type_parameters$>newDefaultInstance(\n"
322 " $descriptor$\n"
323 " $key_wire_type$,\n"
324 " $key_default_value$,\n"
325 " $value_wire_type$,\n"
326 " $value_default_value$);\n"
327 "}\n");
328 printer->Print(variables_,
329 "@SuppressWarnings(\"serial\")\n"
330 "private com.google.protobuf.MapField<\n"
331 " $type_parameters$> $name$_;\n"
332 "private com.google.protobuf.MapField<$type_parameters$>\n"
333 "internalGet$capitalized_name$() {\n"
334 " if ($name$_ == null) {\n"
335 " return com.google.protobuf.MapField.emptyMapField(\n"
336 " $map_field_parameter$);\n"
337 " }\n"
338 " return $name$_;\n"
339 "}\n");
340 if (GetJavaType(MapValueField(descriptor_)) == JAVATYPE_ENUM) {
341 printer->Print(
342 variables_,
343 "private static final\n"
344 "com.google.protobuf.Internal.MapAdapter.Converter<\n"
345 " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
346 " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
347 " $value_enum_type$.internalGetValueMap(),\n"
348 " $unrecognized_value$);\n");
349 printer->Print(
350 variables_,
351 "private static final java.util.Map<$boxed_key_type$, "
352 "$value_enum_type$>\n"
353 "internalGetAdapted$capitalized_name$Map(\n"
354 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n"
355 " return new com.google.protobuf.Internal.MapAdapter<\n"
356 " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
357 " map, $name$ValueConverter);\n"
358 "}\n");
359 }
360 GenerateMapGetters(printer);
361 }
362
GenerateBuilderMembers(io::Printer * printer) const363 void ImmutableMapFieldGenerator::GenerateBuilderMembers(
364 io::Printer* printer) const {
365 if (GetJavaType(MapValueField(descriptor_)) == JAVATYPE_MESSAGE) {
366 return GenerateMessageMapBuilderMembers(printer);
367 }
368 printer->Print(
369 variables_,
370 "private com.google.protobuf.MapField<\n"
371 " $type_parameters$> $name$_;\n"
372 "$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n"
373 " internalGet$capitalized_name$() {\n"
374 " if ($name$_ == null) {\n"
375 " return com.google.protobuf.MapField.emptyMapField(\n"
376 " $map_field_parameter$);\n"
377 " }\n"
378 " return $name$_;\n"
379 "}\n"
380 "$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n"
381 " internalGetMutable$capitalized_name$() {\n"
382 " if ($name$_ == null) {\n"
383 " $name$_ = com.google.protobuf.MapField.newMapField(\n"
384 " $map_field_parameter$);\n"
385 " }\n"
386 " if (!$name$_.isMutable()) {\n"
387 " $name$_ = $name$_.copy();\n"
388 " }\n"
389 " $set_has_field_bit_builder$\n"
390 " $on_changed$\n"
391 " return $name$_;\n"
392 "}\n");
393 GenerateMapGetters(printer);
394 printer->Print(
395 variables_,
396 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
397 " $clear_has_field_bit_builder$\n"
398 " internalGetMutable$capitalized_name$().getMutableMap()\n"
399 " .clear();\n"
400 " return this;\n"
401 "}\n");
402 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
403
404 WriteFieldDocComment(printer, descriptor_, context_->options());
405 printer->Print(variables_,
406 "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n"
407 " $key_type$ key) {\n"
408 " $key_null_check$\n"
409 " internalGetMutable$capitalized_name$().getMutableMap()\n"
410 " .remove(key);\n"
411 " return this;\n"
412 "}\n");
413 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
414
415 const FieldDescriptor* value = MapValueField(descriptor_);
416 if (GetJavaType(value) == JAVATYPE_ENUM) {
417 if (context_->options().opensource_runtime) {
418 printer->Print(
419 variables_,
420 "/**\n"
421 " * Use alternate mutation accessors instead.\n"
422 " */\n"
423 "@java.lang.Deprecated\n"
424 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
425 " ${$getMutable$capitalized_name$$}$() {\n"
426 " $set_has_field_bit_builder$\n"
427 " return internalGetAdapted$capitalized_name$Map(\n"
428 " internalGetMutable$capitalized_name$().getMutableMap());\n"
429 "}\n");
430 printer->Annotate("{", "}", descriptor_);
431 }
432
433 WriteFieldDocComment(printer, descriptor_, context_->options());
434 printer->Print(variables_,
435 "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
436 " $key_type$ key,\n"
437 " $value_enum_type$ value) {\n"
438 " $key_null_check$\n"
439 " $value_null_check$\n"
440 " internalGetMutable$capitalized_name$().getMutableMap()\n"
441 " .put(key, $name$ValueConverter.doBackward(value));\n"
442 " $set_has_field_bit_builder$\n"
443 " return this;\n"
444 "}\n");
445 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
446
447 WriteFieldDocComment(printer, descriptor_, context_->options());
448 printer->Print(
449 variables_,
450 "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
451 " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
452 " internalGetAdapted$capitalized_name$Map(\n"
453 " internalGetMutable$capitalized_name$().getMutableMap())\n"
454 " .putAll(values);\n"
455 " $set_has_field_bit_builder$\n"
456 " return this;\n"
457 "}\n");
458 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
459
460 if (SupportUnknownEnumValue(value)) {
461 if (context_->options().opensource_runtime) {
462 printer->Print(
463 variables_,
464 "/**\n"
465 " * Use alternate mutation accessors instead.\n"
466 " */\n"
467 "@java.lang.Deprecated\n"
468 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
469 "${$getMutable$capitalized_name$Value$}$() {\n"
470 " $set_has_field_bit_builder$\n"
471 " return internalGetMutable$capitalized_name$().getMutableMap();\n"
472 "}\n");
473 printer->Annotate("{", "}", descriptor_);
474 }
475
476 WriteFieldDocComment(printer, descriptor_, context_->options());
477 printer->Print(
478 variables_,
479 "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
480 " $key_type$ key,\n"
481 " $value_type$ value) {\n"
482 " $key_null_check$\n"
483 " $value_null_check$\n"
484 " internalGetMutable$capitalized_name$().getMutableMap()\n"
485 " .put(key, value);\n"
486 " $set_has_field_bit_builder$\n"
487 " return this;\n"
488 "}\n");
489 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
490
491 WriteFieldDocComment(printer, descriptor_, context_->options());
492 printer->Print(
493 variables_,
494 "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
495 " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
496 " internalGetMutable$capitalized_name$().getMutableMap()\n"
497 " .putAll(values);\n"
498 " $set_has_field_bit_builder$\n"
499 " return this;\n"
500 "}\n");
501 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
502 }
503 } else {
504 if (context_->options().opensource_runtime) {
505 printer->Print(
506 variables_,
507 "/**\n"
508 " * Use alternate mutation accessors instead.\n"
509 " */\n"
510 "@java.lang.Deprecated\n"
511 "public java.util.Map<$type_parameters$>\n"
512 " ${$getMutable$capitalized_name$$}$() {\n"
513 " $set_has_field_bit_builder$\n"
514 " return internalGetMutable$capitalized_name$().getMutableMap();\n"
515 "}\n");
516 printer->Annotate("{", "}", descriptor_);
517 }
518
519 WriteFieldDocComment(printer, descriptor_, context_->options());
520 printer->Print(variables_,
521 "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
522 " $key_type$ key,\n"
523 " $value_type$ value) {\n"
524 " $key_null_check$\n"
525 " $value_null_check$\n"
526 " internalGetMutable$capitalized_name$().getMutableMap()\n"
527 " .put(key, value);\n"
528 " $set_has_field_bit_builder$\n"
529 " return this;\n"
530 "}\n");
531 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
532
533 WriteFieldDocComment(printer, descriptor_, context_->options());
534 printer->Print(
535 variables_,
536 "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
537 " java.util.Map<$type_parameters$> values) {\n"
538 " internalGetMutable$capitalized_name$().getMutableMap()\n"
539 " .putAll(values);\n"
540 " $set_has_field_bit_builder$\n"
541 " return this;\n"
542 "}\n");
543 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
544 }
545 }
546
GenerateMapGetters(io::Printer * printer) const547 void ImmutableMapFieldGenerator::GenerateMapGetters(
548 io::Printer* printer) const {
549 printer->Print(
550 variables_,
551 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
552 " return internalGet$capitalized_name$().getMap().size();\n"
553 "}\n");
554 printer->Annotate("{", "}", descriptor_);
555
556 WriteFieldDocComment(printer, descriptor_, context_->options());
557 printer->Print(
558 variables_,
559 "@java.lang.Override\n"
560 "$deprecation$public boolean ${$contains$capitalized_name$$}$(\n"
561 " $key_type$ key) {\n"
562 " $key_null_check$\n"
563 " return internalGet$capitalized_name$().getMap().containsKey(key);\n"
564 "}\n");
565 printer->Annotate("{", "}", descriptor_);
566
567 const FieldDescriptor* value = MapValueField(descriptor_);
568 if (GetJavaType(value) == JAVATYPE_ENUM) {
569 if (context_->options().opensource_runtime) {
570 printer->Print(
571 variables_,
572 "/**\n"
573 " * Use {@link #get$capitalized_name$Map()} instead.\n"
574 " */\n"
575 "@java.lang.Override\n"
576 "@java.lang.Deprecated\n"
577 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
578 "${$get$capitalized_name$$}$() {\n"
579 " return get$capitalized_name$Map();\n"
580 "}\n");
581 printer->Annotate("{", "}", descriptor_);
582 }
583
584 WriteFieldDocComment(printer, descriptor_, context_->options());
585 printer->Print(variables_,
586 "@java.lang.Override\n"
587 "$deprecation$public java.util.Map<$boxed_key_type$, "
588 "$value_enum_type$>\n"
589 "${$get$capitalized_name$Map$}$() {\n"
590 " return internalGetAdapted$capitalized_name$Map(\n"
591 " internalGet$capitalized_name$().getMap());"
592 "}\n");
593 printer->Annotate("{", "}", descriptor_);
594
595 WriteFieldDocComment(printer, descriptor_, context_->options());
596 printer->Print(
597 variables_,
598 "@java.lang.Override\n"
599 "$deprecation$public $value_enum_type_pass_through_nullness$ "
600 "${$get$capitalized_name$OrDefault$}$(\n"
601 " $key_type$ key,\n"
602 " $value_enum_type_pass_through_nullness$ defaultValue) {\n"
603 " $key_null_check$\n"
604 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
605 " internalGet$capitalized_name$().getMap();\n"
606 " return map.containsKey(key)\n"
607 " ? $name$ValueConverter.doForward(map.get(key))\n"
608 " : defaultValue;\n"
609 "}\n");
610 printer->Annotate("{", "}", descriptor_);
611
612 WriteFieldDocComment(printer, descriptor_, context_->options());
613 printer->Print(
614 variables_,
615 "@java.lang.Override\n"
616 "$deprecation$public $value_enum_type$ "
617 "${$get$capitalized_name$OrThrow$}$(\n"
618 " $key_type$ key) {\n"
619 " $key_null_check$\n"
620 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
621 " internalGet$capitalized_name$().getMap();\n"
622 " if (!map.containsKey(key)) {\n"
623 " throw new java.lang.IllegalArgumentException();\n"
624 " }\n"
625 " return $name$ValueConverter.doForward(map.get(key));\n"
626 "}\n");
627 printer->Annotate("{", "}", descriptor_);
628
629 if (SupportUnknownEnumValue(value)) {
630 printer->Print(
631 variables_,
632 "/**\n"
633 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
634 " */\n"
635 "@java.lang.Override\n"
636 "@java.lang.Deprecated\n"
637 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
638 "${$get$capitalized_name$Value$}$() {\n"
639 " return get$capitalized_name$ValueMap();\n"
640 "}\n");
641 printer->Annotate("{", "}", descriptor_);
642 WriteFieldDocComment(printer, descriptor_, context_->options());
643 printer->Print(variables_,
644 "@java.lang.Override\n"
645 "$deprecation$public java.util.Map<$boxed_key_type$, "
646 "$boxed_value_type$>\n"
647 "${$get$capitalized_name$ValueMap$}$() {\n"
648 " return internalGet$capitalized_name$().getMap();\n"
649 "}\n");
650 printer->Annotate("{", "}", descriptor_);
651 WriteFieldDocComment(printer, descriptor_, context_->options());
652 printer->Print(
653 variables_,
654 "@java.lang.Override\n"
655 "$deprecation$public $value_type_pass_through_nullness$ "
656 "${$get$capitalized_name$ValueOrDefault$}$(\n"
657 " $key_type$ key,\n"
658 " $value_type_pass_through_nullness$ defaultValue) {\n"
659 " $key_null_check$\n"
660 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
661 " internalGet$capitalized_name$().getMap();\n"
662 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
663 "}\n");
664 printer->Annotate("{", "}", descriptor_);
665 WriteFieldDocComment(printer, descriptor_, context_->options());
666 printer->Print(
667 variables_,
668 "@java.lang.Override\n"
669 "$deprecation$public $value_type$ "
670 "${$get$capitalized_name$ValueOrThrow$}$(\n"
671 " $key_type$ key) {\n"
672 " $key_null_check$\n"
673 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
674 " internalGet$capitalized_name$().getMap();\n"
675 " if (!map.containsKey(key)) {\n"
676 " throw new java.lang.IllegalArgumentException();\n"
677 " }\n"
678 " return map.get(key);\n"
679 "}\n");
680 printer->Annotate("{", "}", descriptor_);
681 }
682 } else {
683 if (context_->options().opensource_runtime) {
684 printer->Print(variables_,
685 "/**\n"
686 " * Use {@link #get$capitalized_name$Map()} instead.\n"
687 " */\n"
688 "@java.lang.Override\n"
689 "@java.lang.Deprecated\n"
690 "public java.util.Map<$type_parameters$> "
691 "${$get$capitalized_name$$}$() {\n"
692 " return get$capitalized_name$Map();\n"
693 "}\n");
694 printer->Annotate("{", "}", descriptor_);
695 }
696 WriteFieldDocComment(printer, descriptor_, context_->options());
697 printer->Print(variables_,
698 "@java.lang.Override\n"
699 "$deprecation$public java.util.Map<$type_parameters$> "
700 "${$get$capitalized_name$Map$}$() {\n"
701 " return internalGet$capitalized_name$().getMap();\n"
702 "}\n");
703 printer->Annotate("{", "}", descriptor_);
704 WriteFieldDocComment(printer, descriptor_, context_->options());
705 printer->Print(
706 variables_,
707 "@java.lang.Override\n"
708 "$deprecation$public $value_type_pass_through_nullness$ "
709 "${$get$capitalized_name$OrDefault$}$(\n"
710 " $key_type$ key,\n"
711 " $value_type_pass_through_nullness$ defaultValue) {\n"
712 " $key_null_check$\n"
713 " java.util.Map<$type_parameters$> map =\n"
714 " internalGet$capitalized_name$().getMap();\n"
715 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
716 "}\n");
717 printer->Annotate("{", "}", descriptor_);
718 WriteFieldDocComment(printer, descriptor_, context_->options());
719 printer->Print(
720 variables_,
721 "@java.lang.Override\n"
722 "$deprecation$public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
723 " $key_type$ key) {\n"
724 " $key_null_check$\n"
725 " java.util.Map<$type_parameters$> map =\n"
726 " internalGet$capitalized_name$().getMap();\n"
727 " if (!map.containsKey(key)) {\n"
728 " throw new java.lang.IllegalArgumentException();\n"
729 " }\n"
730 " return map.get(key);\n"
731 "}\n");
732 printer->Annotate("{", "}", descriptor_);
733 }
734 }
735
GenerateMessageMapBuilderMembers(io::Printer * printer) const736 void ImmutableMapFieldGenerator::GenerateMessageMapBuilderMembers(
737 io::Printer* printer) const {
738 printer->Print(
739 variables_,
740 "private static final class $capitalized_name$Converter implements "
741 "com.google.protobuf.MapFieldBuilder.Converter<$boxed_key_type$, "
742 "$value_interface_type$, $boxed_value_type$> "
743 "{\n");
744 {
745 auto i1 = printer->WithIndent();
746 printer->Print("@java.lang.Override\n");
747 printer->Print(
748 variables_,
749 "public $boxed_value_type$ build($value_interface_type$ val) {\n");
750 {
751 auto i2 = printer->WithIndent();
752 printer->Print(variables_,
753 "if (val instanceof $boxed_value_type$) {"
754 " return ($boxed_value_type$) val; }\n");
755 printer->Print(variables_,
756 "return (($value_builder_type$) val).build();\n");
757 }
758 printer->Print("}\n\n");
759
760 printer->Print("@java.lang.Override\n");
761 printer->Print(variables_,
762 "public com.google.protobuf.MapEntry<$boxed_key_type$, "
763 "$boxed_value_type$> defaultEntry() {\n");
764 {
765 auto i2 = printer->WithIndent();
766 printer->Print(
767 variables_,
768 "return $capitalized_name$DefaultEntryHolder.defaultEntry;\n");
769 }
770 printer->Print("}\n");
771 }
772 printer->Print("};\n");
773 printer->Print(variables_,
774 "private static final $capitalized_name$Converter "
775 "$name$Converter = new $capitalized_name$Converter();\n\n");
776
777 printer->Print(
778 variables_,
779 "private com.google.protobuf.MapFieldBuilder<\n"
780 " $builder_type_parameters$> $name$_;\n"
781 "$deprecation$private "
782 "com.google.protobuf.MapFieldBuilder<$builder_type_parameters$>\n"
783 " internalGet$capitalized_name$() {\n"
784 " if ($name$_ == null) {\n"
785 " return new com.google.protobuf.MapFieldBuilder<>($name$Converter);\n"
786 " }\n"
787 " return $name$_;\n"
788 "}\n"
789 "$deprecation$private "
790 "com.google.protobuf.MapFieldBuilder<$builder_type_parameters$>\n"
791 " internalGetMutable$capitalized_name$() {\n"
792 " if ($name$_ == null) {\n"
793 " $name$_ = new "
794 "com.google.protobuf.MapFieldBuilder<>($name$Converter);\n"
795 " }\n"
796 " $set_has_field_bit_builder$\n"
797 " $on_changed$\n"
798 " return $name$_;\n"
799 "}\n");
800 GenerateMessageMapGetters(printer);
801 printer->Print(
802 variables_,
803 "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
804 " $clear_has_field_bit_builder$\n"
805 " internalGetMutable$capitalized_name$().clear();\n"
806 " return this;\n"
807 "}\n");
808 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
809
810 WriteFieldDocComment(printer, descriptor_, context_->options());
811 printer->Print(variables_,
812 "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n"
813 " $key_type$ key) {\n"
814 " $key_null_check$\n"
815 " internalGetMutable$capitalized_name$().ensureBuilderMap()\n"
816 " .remove(key);\n"
817 " return this;\n"
818 "}\n");
819 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
820
821 if (context_->options().opensource_runtime) {
822 printer->Print(
823 variables_,
824 "/**\n"
825 " * Use alternate mutation accessors instead.\n"
826 " */\n"
827 "@java.lang.Deprecated\n"
828 "public java.util.Map<$type_parameters$>\n"
829 " ${$getMutable$capitalized_name$$}$() {\n"
830 " $set_has_field_bit_builder$\n"
831 " return internalGetMutable$capitalized_name$().ensureMessageMap();\n"
832 "}\n");
833 printer->Annotate("{", "}", descriptor_);
834 }
835
836 WriteFieldDocComment(printer, descriptor_, context_->options());
837 printer->Print(variables_,
838 "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
839 " $key_type$ key,\n"
840 " $value_type$ value) {\n"
841 " $key_null_check$\n"
842 " $value_null_check$\n"
843 " internalGetMutable$capitalized_name$().ensureBuilderMap()\n"
844 " .put(key, value);\n"
845 " $set_has_field_bit_builder$\n"
846 " return this;\n"
847 "}\n");
848 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
849
850 WriteFieldDocComment(printer, descriptor_, context_->options());
851 printer->Print(
852 variables_,
853 "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
854 " java.util.Map<$type_parameters$> values) {\n"
855 " for (java.util.Map.Entry<$type_parameters$> e : values.entrySet()) {\n"
856 " if (e.getKey() == null || e.getValue() == null) {\n"
857 " throw new NullPointerException();\n"
858 " }\n"
859 " }\n"
860 " internalGetMutable$capitalized_name$().ensureBuilderMap()\n"
861 " .putAll(values);\n"
862 " $set_has_field_bit_builder$\n"
863 " return this;\n"
864 "}\n");
865 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
866
867 WriteFieldDocComment(printer, descriptor_, context_->options());
868 printer->Print(
869 variables_,
870 "$deprecation$public $value_builder_type$ "
871 "${$put$capitalized_name$BuilderIfAbsent$}$(\n"
872 " $key_type$ key) {\n"
873 " java.util.Map<$boxed_key_type$, $value_interface_type$> builderMap = "
874 "internalGetMutable$capitalized_name$().ensureBuilderMap();\n"
875 " $value_interface_type$ entry = builderMap.get(key);\n"
876 " if (entry == null) {\n"
877 " entry = $value_type$.newBuilder();\n"
878 " builderMap.put(key, entry);\n"
879 " }\n"
880 " if (entry instanceof $value_type$) {\n"
881 " entry = (($value_type$) entry).toBuilder();\n"
882 " builderMap.put(key, entry);\n"
883 " }\n"
884 " return ($value_builder_type$) entry;\n"
885 "}\n");
886 printer->Annotate("{", "}", descriptor_, Semantic::kSet);
887 }
888
GenerateMessageMapGetters(io::Printer * printer) const889 void ImmutableMapFieldGenerator::GenerateMessageMapGetters(
890 io::Printer* printer) const {
891 printer->Print(
892 variables_,
893 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
894 " return internalGet$capitalized_name$().ensureBuilderMap().size();\n"
895 "}\n");
896 printer->Annotate("{", "}", descriptor_);
897
898 WriteFieldDocComment(printer, descriptor_, context_->options());
899 printer->Print(
900 variables_,
901 "@java.lang.Override\n"
902 "$deprecation$public boolean ${$contains$capitalized_name$$}$(\n"
903 " $key_type$ key) {\n"
904 " $key_null_check$\n"
905 " return "
906 "internalGet$capitalized_name$().ensureBuilderMap().containsKey(key);\n"
907 "}\n");
908 printer->Annotate("{", "}", descriptor_);
909 if (context_->options().opensource_runtime) {
910 printer->Print(variables_,
911 "/**\n"
912 " * Use {@link #get$capitalized_name$Map()} instead.\n"
913 " */\n"
914 "@java.lang.Override\n"
915 "@java.lang.Deprecated\n"
916 "public java.util.Map<$type_parameters$> "
917 "${$get$capitalized_name$$}$() {\n"
918 " return get$capitalized_name$Map();\n"
919 "}\n");
920 printer->Annotate("{", "}", descriptor_);
921 }
922 WriteFieldDocComment(printer, descriptor_, context_->options());
923 printer->Print(variables_,
924 "@java.lang.Override\n"
925 "$deprecation$public java.util.Map<$type_parameters$> "
926 "${$get$capitalized_name$Map$}$() {\n"
927 " return internalGet$capitalized_name$().getImmutableMap();\n"
928 "}\n");
929 printer->Annotate("{", "}", descriptor_);
930 WriteFieldDocComment(printer, descriptor_, context_->options());
931 printer->Print(
932 variables_,
933 "@java.lang.Override\n"
934 "$deprecation$public $value_type_pass_through_nullness$ "
935 "${$get$capitalized_name$OrDefault$}$(\n"
936 " $key_type$ key,\n"
937 " $value_type_pass_through_nullness$ defaultValue) {\n"
938 " $key_null_check$\n"
939 " java.util.Map<$boxed_key_type$, $value_interface_type$> map = "
940 "internalGetMutable$capitalized_name$().ensureBuilderMap();\n"
941 " return map.containsKey(key) ? $name$Converter.build(map.get(key)) : "
942 "defaultValue;\n"
943 "}\n");
944 printer->Annotate("{", "}", descriptor_);
945 WriteFieldDocComment(printer, descriptor_, context_->options());
946 printer->Print(
947 variables_,
948 "@java.lang.Override\n"
949 "$deprecation$public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
950 " $key_type$ key) {\n"
951 " $key_null_check$\n"
952 " java.util.Map<$boxed_key_type$, $value_interface_type$> map = "
953 "internalGetMutable$capitalized_name$().ensureBuilderMap();\n"
954 " if (!map.containsKey(key)) {\n"
955 " throw new java.lang.IllegalArgumentException();\n"
956 " }\n"
957 " return $name$Converter.build(map.get(key));\n"
958 "}\n");
959 printer->Annotate("{", "}", descriptor_);
960 }
961
GenerateKotlinDslMembers(io::Printer * printer) const962 void ImmutableMapFieldGenerator::GenerateKotlinDslMembers(
963 io::Printer* printer) const {
964 printer->Print(
965 variables_,
966 "/**\n"
967 " * An uninstantiable, behaviorless type to represent the field in\n"
968 " * generics.\n"
969 " */\n"
970 "@kotlin.OptIn"
971 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
972 "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
973 " : com.google.protobuf.kotlin.DslProxy()\n");
974
975 WriteFieldDocComment(printer, descriptor_, context_->options(),
976 /* kdoc */ true);
977 printer->Print(
978 variables_,
979 "$kt_deprecation$ public val $kt_name$: "
980 "com.google.protobuf.kotlin.DslMap"
981 "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
982 " @kotlin.jvm.JvmSynthetic\n"
983 " @JvmName(\"get$kt_capitalized_name$Map\")\n"
984 " get() = com.google.protobuf.kotlin.DslMap(\n"
985 " $kt_dsl_builder$.${$$kt_property_name$Map$}$\n"
986 " )\n");
987
988 WriteFieldDocComment(printer, descriptor_, context_->options(),
989 /* kdoc */ true);
990 printer->Print(
991 variables_,
992 "@JvmName(\"put$kt_capitalized_name$\")\n"
993 "public fun com.google.protobuf.kotlin.DslMap"
994 "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
995 " .put(key: $kt_key_type$, value: $kt_value_type$) {\n"
996 " $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n"
997 " }\n");
998
999 WriteFieldDocComment(printer, descriptor_, context_->options(),
1000 /* kdoc */ true);
1001 printer->Print(
1002 variables_,
1003 "@kotlin.jvm.JvmSynthetic\n"
1004 "@JvmName(\"set$kt_capitalized_name$\")\n"
1005 "@Suppress(\"NOTHING_TO_INLINE\")\n"
1006 "public inline operator fun com.google.protobuf.kotlin.DslMap"
1007 "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1008 " .set(key: $kt_key_type$, value: $kt_value_type$) {\n"
1009 " put(key, value)\n"
1010 " }\n");
1011
1012 WriteFieldDocComment(printer, descriptor_, context_->options(),
1013 /* kdoc */ true);
1014 printer->Print(
1015 variables_,
1016 "@kotlin.jvm.JvmSynthetic\n"
1017 "@JvmName(\"remove$kt_capitalized_name$\")\n"
1018 "public fun com.google.protobuf.kotlin.DslMap"
1019 "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1020 " .remove(key: $kt_key_type$) {\n"
1021 " $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n"
1022 " }\n");
1023
1024 WriteFieldDocComment(printer, descriptor_, context_->options(),
1025 /* kdoc */ true);
1026 printer->Print(
1027 variables_,
1028 "@kotlin.jvm.JvmSynthetic\n"
1029 "@JvmName(\"putAll$kt_capitalized_name$\")\n"
1030 "public fun com.google.protobuf.kotlin.DslMap"
1031 "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1032 " .putAll(map: kotlin.collections.Map<$kt_key_type$, "
1033 "$kt_value_type$>) "
1034 "{\n"
1035 " $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n"
1036 " }\n");
1037
1038 WriteFieldDocComment(printer, descriptor_, context_->options(),
1039 /* kdoc */ true);
1040 printer->Print(
1041 variables_,
1042 "@kotlin.jvm.JvmSynthetic\n"
1043 "@JvmName(\"clear$kt_capitalized_name$\")\n"
1044 "public fun com.google.protobuf.kotlin.DslMap"
1045 "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1046 " .clear() {\n"
1047 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
1048 " }\n");
1049 }
1050
GenerateFieldBuilderInitializationCode(io::Printer * printer) const1051 void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode(
1052 io::Printer* printer) const {
1053 // Nothing to initialize.
1054 }
1055
GenerateInitializationCode(io::Printer * printer) const1056 void ImmutableMapFieldGenerator::GenerateInitializationCode(
1057 io::Printer* printer) const {
1058 // Nothing to initialize.
1059 }
1060
GenerateBuilderClearCode(io::Printer * printer) const1061 void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
1062 io::Printer* printer) const {
1063 // No need to clear the has-bit since we clear the bitField ints all at once.
1064 printer->Print(variables_,
1065 "internalGetMutable$capitalized_name$().clear();\n");
1066 }
1067
GenerateMergingCode(io::Printer * printer) const1068 void ImmutableMapFieldGenerator::GenerateMergingCode(
1069 io::Printer* printer) const {
1070 printer->Print(variables_,
1071 "internalGetMutable$capitalized_name$().mergeFrom(\n"
1072 " other.internalGet$capitalized_name$());\n"
1073 "$set_has_field_bit_builder$\n");
1074 }
1075
GenerateBuildingCode(io::Printer * printer) const1076 void ImmutableMapFieldGenerator::GenerateBuildingCode(
1077 io::Printer* printer) const {
1078 if (GetJavaType(MapValueField(descriptor_)) == JAVATYPE_MESSAGE) {
1079 printer->Print(
1080 variables_,
1081 "if ($get_has_field_bit_from_local$) {\n"
1082 " result.$name$_ = "
1083 "internalGet$capitalized_name$().build($map_field_parameter$);\n"
1084 "}\n");
1085 return;
1086 }
1087 printer->Print(variables_,
1088 "if ($get_has_field_bit_from_local$) {\n"
1089 " result.$name$_ = internalGet$capitalized_name$();\n"
1090 " result.$name$_.makeImmutable();\n"
1091 "}\n");
1092 }
1093
GenerateBuilderParsingCode(io::Printer * printer) const1094 void ImmutableMapFieldGenerator::GenerateBuilderParsingCode(
1095 io::Printer* printer) const {
1096 const FieldDescriptor* value = MapValueField(descriptor_);
1097 const JavaType type = GetJavaType(value);
1098 if (type == JAVATYPE_MESSAGE) {
1099 printer->Print(
1100 variables_,
1101 "com.google.protobuf.MapEntry<$type_parameters$>\n"
1102 "$name$__ = input.readMessage(\n"
1103 " $default_entry$.getParserForType(), extensionRegistry);\n"
1104 "internalGetMutable$capitalized_name$().ensureBuilderMap().put(\n"
1105 " $name$__.getKey(), $name$__.getValue());\n"
1106 "$set_has_field_bit_builder$\n");
1107 return;
1108 }
1109 if (!SupportUnknownEnumValue(value) && type == JAVATYPE_ENUM) {
1110 printer->Print(
1111 variables_,
1112 "com.google.protobuf.ByteString bytes = input.readBytes();\n"
1113 "com.google.protobuf.MapEntry<$type_parameters$>\n"
1114 "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n"
1115 "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n"
1116 " mergeUnknownLengthDelimitedField($number$, bytes);\n"
1117 "} else {\n"
1118 " internalGetMutable$capitalized_name$().getMutableMap().put(\n"
1119 " $name$__.getKey(), $name$__.getValue());\n"
1120 " $set_has_field_bit_builder$\n"
1121 "}\n");
1122 return;
1123 }
1124 printer->Print(variables_,
1125 "com.google.protobuf.MapEntry<$type_parameters$>\n"
1126 "$name$__ = input.readMessage(\n"
1127 " $default_entry$.getParserForType(), extensionRegistry);\n"
1128 "internalGetMutable$capitalized_name$().getMutableMap().put(\n"
1129 " $name$__.getKey(), $name$__.getValue());\n"
1130 "$set_has_field_bit_builder$\n");
1131 }
GenerateSerializationCode(io::Printer * printer) const1132 void ImmutableMapFieldGenerator::GenerateSerializationCode(
1133 io::Printer* printer) const {
1134 printer->Print(variables_,
1135 "com.google.protobuf.GeneratedMessage\n"
1136 " .serialize$short_key_type$MapTo(\n"
1137 " output,\n"
1138 " internalGet$capitalized_name$(),\n"
1139 " $default_entry$,\n"
1140 " $number$);\n");
1141 }
1142
GenerateSerializedSizeCode(io::Printer * printer) const1143 void ImmutableMapFieldGenerator::GenerateSerializedSizeCode(
1144 io::Printer* printer) const {
1145 printer->Print(
1146 variables_,
1147 "for (java.util.Map.Entry<$type_parameters$> entry\n"
1148 " : internalGet$capitalized_name$().getMap().entrySet()) {\n"
1149 " com.google.protobuf.MapEntry<$type_parameters$>\n"
1150 " $name$__ = $default_entry$.newBuilderForType()\n"
1151 " .setKey(entry.getKey())\n"
1152 " .setValue(entry.getValue())\n"
1153 " .build();\n"
1154 " size += com.google.protobuf.CodedOutputStream\n"
1155 " .computeMessageSize($number$, $name$__);\n"
1156 "}\n");
1157 }
1158
GenerateEqualsCode(io::Printer * printer) const1159 void ImmutableMapFieldGenerator::GenerateEqualsCode(
1160 io::Printer* printer) const {
1161 printer->Print(variables_,
1162 "if (!internalGet$capitalized_name$().equals(\n"
1163 " other.internalGet$capitalized_name$())) return false;\n");
1164 }
1165
GenerateHashCode(io::Printer * printer) const1166 void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const {
1167 printer->Print(
1168 variables_,
1169 "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
1170 " hash = (37 * hash) + $constant_name$;\n"
1171 " hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
1172 "}\n");
1173 }
1174
GetBoxedType() const1175 std::string ImmutableMapFieldGenerator::GetBoxedType() const {
1176 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
1177 }
1178
1179 } // namespace java
1180 } // namespace compiler
1181 } // namespace protobuf
1182 } // namespace google
1183
1184 #include "google/protobuf/port_undef.inc"
1185