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