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 (*variables)["default_entry"] =
142 (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
143 (*variables)["map_field_parameter"] = (*variables)["default_entry"];
144 (*variables)["descriptor"] =
145 name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" +
146 UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, ";
147 (*variables)["ver"] = GeneratedCodeVersionSuffix();
148 }
149
150 } // namespace
151
ImmutableMapFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)152 ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
153 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
154 Context* context)
155 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
156 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
157 context->GetFieldGeneratorInfo(descriptor), context,
158 &variables_);
159 }
160
~ImmutableMapFieldGenerator()161 ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {}
162
GetNumBitsForMessage() const163 int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; }
164
GetNumBitsForBuilder() const165 int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; }
166
GenerateInterfaceMembers(io::Printer * printer) const167 void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
168 io::Printer* printer) const {
169 WriteFieldDocComment(printer, descriptor_);
170 printer->Print(variables_,
171 "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
172 printer->Annotate("{", "}", descriptor_);
173 WriteFieldDocComment(printer, descriptor_);
174 printer->Print(variables_,
175 "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
176 " $key_type$ key);\n");
177 printer->Annotate("{", "}", descriptor_);
178 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
179 printer->Print(variables_,
180 "/**\n"
181 " * Use {@link #get$capitalized_name$Map()} instead.\n"
182 " */\n"
183 "@java.lang.Deprecated\n"
184 "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
185 "${$get$capitalized_name$$}$();\n");
186 printer->Annotate("{", "}", descriptor_);
187 WriteFieldDocComment(printer, descriptor_);
188 printer->Print(
189 variables_,
190 "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
191 "${$get$capitalized_name$Map$}$();\n");
192 printer->Annotate("{", "}", descriptor_);
193 WriteFieldDocComment(printer, descriptor_);
194 printer->Print(
195 variables_,
196 "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
197 " $key_type$ key,\n"
198 " $value_enum_type$ defaultValue);\n");
199 printer->Annotate("{", "}", descriptor_);
200 WriteFieldDocComment(printer, descriptor_);
201 printer->Print(
202 variables_,
203 "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
204 " $key_type$ key);\n");
205 printer->Annotate("{", "}", descriptor_);
206 if (SupportUnknownEnumValue(descriptor_->file())) {
207 printer->Print(
208 variables_,
209 "/**\n"
210 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
211 " */\n"
212 "@java.lang.Deprecated\n"
213 "java.util.Map<$type_parameters$>\n"
214 "${$get$capitalized_name$Value$}$();\n");
215 printer->Annotate("{", "}", descriptor_);
216 WriteFieldDocComment(printer, descriptor_);
217 printer->Print(variables_,
218 "$deprecation$java.util.Map<$type_parameters$>\n"
219 "${$get$capitalized_name$ValueMap$}$();\n");
220 printer->Annotate("{", "}", descriptor_);
221 WriteFieldDocComment(printer, descriptor_);
222 printer->Print(variables_,
223 "$deprecation$\n"
224 "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
225 " $key_type$ key,\n"
226 " $value_type$ defaultValue);\n");
227 printer->Annotate("{", "}", descriptor_);
228 WriteFieldDocComment(printer, descriptor_);
229 printer->Print(variables_,
230 "$deprecation$\n"
231 "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
232 " $key_type$ key);\n");
233 printer->Annotate("{", "}", descriptor_);
234 }
235 } else {
236 printer->Print(variables_,
237 "/**\n"
238 " * Use {@link #get$capitalized_name$Map()} instead.\n"
239 " */\n"
240 "@java.lang.Deprecated\n"
241 "java.util.Map<$type_parameters$>\n"
242 "${$get$capitalized_name$$}$();\n");
243 printer->Annotate("{", "}", descriptor_);
244 WriteFieldDocComment(printer, descriptor_);
245 printer->Print(variables_,
246 "$deprecation$java.util.Map<$type_parameters$>\n"
247 "${$get$capitalized_name$Map$}$();\n");
248 printer->Annotate("{", "}", descriptor_);
249 WriteFieldDocComment(printer, descriptor_);
250 printer->Print(variables_,
251 "$deprecation$\n"
252 "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
253 " $key_type$ key,\n"
254 " $value_type$ defaultValue);\n");
255 printer->Annotate("{", "}", descriptor_);
256 WriteFieldDocComment(printer, descriptor_);
257 printer->Print(variables_,
258 "$deprecation$\n"
259 "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
260 " $key_type$ key);\n");
261 printer->Annotate("{", "}", descriptor_);
262 }
263 }
264
GenerateMembers(io::Printer * printer) const265 void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
266 printer->Print(
267 variables_,
268 "private static final class $capitalized_name$DefaultEntryHolder {\n"
269 " static final com.google.protobuf.MapEntry<\n"
270 " $type_parameters$> defaultEntry =\n"
271 " com.google.protobuf.MapEntry\n"
272 " .<$type_parameters$>newDefaultInstance(\n"
273 " $descriptor$\n"
274 " $key_wire_type$,\n"
275 " $key_default_value$,\n"
276 " $value_wire_type$,\n"
277 " $value_default_value$);\n"
278 "}\n");
279 printer->Print(variables_,
280 "private com.google.protobuf.MapField<\n"
281 " $type_parameters$> $name$_;\n"
282 "private com.google.protobuf.MapField<$type_parameters$>\n"
283 "internalGet$capitalized_name$() {\n"
284 " if ($name$_ == null) {\n"
285 " return com.google.protobuf.MapField.emptyMapField(\n"
286 " $map_field_parameter$);\n"
287 " }\n"
288 " return $name$_;\n"
289 "}\n");
290 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
291 printer->Print(
292 variables_,
293 "private static final\n"
294 "com.google.protobuf.Internal.MapAdapter.Converter<\n"
295 " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
296 " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
297 " $value_enum_type$.internalGetValueMap(),\n"
298 " $unrecognized_value$);\n");
299 printer->Print(
300 variables_,
301 "private static final java.util.Map<$boxed_key_type$, "
302 "$value_enum_type$>\n"
303 "internalGetAdapted$capitalized_name$Map(\n"
304 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n"
305 " return new com.google.protobuf.Internal.MapAdapter<\n"
306 " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
307 " map, $name$ValueConverter);\n"
308 "}\n");
309 }
310 GenerateMapGetters(printer);
311 }
312
GenerateBuilderMembers(io::Printer * printer) const313 void ImmutableMapFieldGenerator::GenerateBuilderMembers(
314 io::Printer* printer) const {
315 printer->Print(variables_,
316 "private com.google.protobuf.MapField<\n"
317 " $type_parameters$> $name$_;\n"
318 "private com.google.protobuf.MapField<$type_parameters$>\n"
319 "internalGet$capitalized_name$() {\n"
320 " if ($name$_ == null) {\n"
321 " return com.google.protobuf.MapField.emptyMapField(\n"
322 " $map_field_parameter$);\n"
323 " }\n"
324 " return $name$_;\n"
325 "}\n"
326 "private com.google.protobuf.MapField<$type_parameters$>\n"
327 "internalGetMutable$capitalized_name$() {\n"
328 " $on_changed$;\n"
329 " if ($name$_ == null) {\n"
330 " $name$_ = com.google.protobuf.MapField.newMapField(\n"
331 " $map_field_parameter$);\n"
332 " }\n"
333 " if (!$name$_.isMutable()) {\n"
334 " $name$_ = $name$_.copy();\n"
335 " }\n"
336 " return $name$_;\n"
337 "}\n");
338 GenerateMapGetters(printer);
339 printer->Print(variables_,
340 "$deprecation$\n"
341 "public Builder ${$clear$capitalized_name$$}$() {\n"
342 " internalGetMutable$capitalized_name$().getMutableMap()\n"
343 " .clear();\n"
344 " return this;\n"
345 "}\n");
346 printer->Annotate("{", "}", descriptor_);
347 WriteFieldDocComment(printer, descriptor_);
348 printer->Print(variables_,
349 "$deprecation$\n"
350 "public Builder ${$remove$capitalized_name$$}$(\n"
351 " $key_type$ key) {\n"
352 " $key_null_check$\n"
353 " internalGetMutable$capitalized_name$().getMutableMap()\n"
354 " .remove(key);\n"
355 " return this;\n"
356 "}\n");
357 printer->Annotate("{", "}", descriptor_);
358 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
359 printer->Print(
360 variables_,
361 "/**\n"
362 " * Use alternate mutation accessors instead.\n"
363 " */\n"
364 "@java.lang.Deprecated\n"
365 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
366 "${$getMutable$capitalized_name$$}$() {\n"
367 " return internalGetAdapted$capitalized_name$Map(\n"
368 " internalGetMutable$capitalized_name$().getMutableMap());\n"
369 "}\n");
370 printer->Annotate("{", "}", descriptor_);
371 WriteFieldDocComment(printer, descriptor_);
372 printer->Print(variables_,
373 "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
374 " $key_type$ key,\n"
375 " $value_enum_type$ value) {\n"
376 " $key_null_check$\n"
377 " $value_null_check$\n"
378 " internalGetMutable$capitalized_name$().getMutableMap()\n"
379 " .put(key, $name$ValueConverter.doBackward(value));\n"
380 " return this;\n"
381 "}\n");
382 printer->Annotate("{", "}", descriptor_);
383 WriteFieldDocComment(printer, descriptor_);
384 printer->Print(
385 variables_,
386 "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
387 " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
388 " internalGetAdapted$capitalized_name$Map(\n"
389 " internalGetMutable$capitalized_name$().getMutableMap())\n"
390 " .putAll(values);\n"
391 " return this;\n"
392 "}\n");
393 printer->Annotate("{", "}", descriptor_);
394 if (SupportUnknownEnumValue(descriptor_->file())) {
395 printer->Print(
396 variables_,
397 "/**\n"
398 " * Use alternate mutation accessors instead.\n"
399 " */\n"
400 "@java.lang.Deprecated\n"
401 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
402 "${$getMutable$capitalized_name$Value$}$() {\n"
403 " return internalGetMutable$capitalized_name$().getMutableMap();\n"
404 "}\n");
405 printer->Annotate("{", "}", descriptor_);
406 WriteFieldDocComment(printer, descriptor_);
407 printer->Print(
408 variables_,
409 "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
410 " $key_type$ key,\n"
411 " $value_type$ value) {\n"
412 " $key_null_check$\n"
413 " internalGetMutable$capitalized_name$().getMutableMap()\n"
414 " .put(key, value);\n"
415 " return this;\n"
416 "}\n");
417 printer->Annotate("{", "}", descriptor_);
418 WriteFieldDocComment(printer, descriptor_);
419 printer->Print(
420 variables_,
421 "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
422 " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
423 " internalGetMutable$capitalized_name$().getMutableMap()\n"
424 " .putAll(values);\n"
425 " return this;\n"
426 "}\n");
427 printer->Annotate("{", "}", descriptor_);
428 }
429 } else {
430 printer->Print(
431 variables_,
432 "/**\n"
433 " * Use alternate mutation accessors instead.\n"
434 " */\n"
435 "@java.lang.Deprecated\n"
436 "public java.util.Map<$type_parameters$>\n"
437 "${$getMutable$capitalized_name$$}$() {\n"
438 " return internalGetMutable$capitalized_name$().getMutableMap();\n"
439 "}\n");
440 printer->Annotate("{", "}", descriptor_);
441 WriteFieldDocComment(printer, descriptor_);
442 printer->Print(variables_,
443 "$deprecation$"
444 "public Builder ${$put$capitalized_name$$}$(\n"
445 " $key_type$ key,\n"
446 " $value_type$ value) {\n"
447 " $key_null_check$\n"
448 " $value_null_check$\n"
449 " internalGetMutable$capitalized_name$().getMutableMap()\n"
450 " .put(key, value);\n"
451 " return this;\n"
452 "}\n");
453 printer->Annotate("{", "}", descriptor_);
454 WriteFieldDocComment(printer, descriptor_);
455 printer->Print(variables_,
456 "$deprecation$\n"
457 "public Builder ${$putAll$capitalized_name$$}$(\n"
458 " java.util.Map<$type_parameters$> values) {\n"
459 " internalGetMutable$capitalized_name$().getMutableMap()\n"
460 " .putAll(values);\n"
461 " return this;\n"
462 "}\n");
463 printer->Annotate("{", "}", descriptor_);
464 }
465 }
466
GenerateMapGetters(io::Printer * printer) const467 void ImmutableMapFieldGenerator::GenerateMapGetters(
468 io::Printer* printer) const {
469 printer->Print(variables_,
470 "$deprecation$\n"
471 "public int ${$get$capitalized_name$Count$}$() {\n"
472 " return internalGet$capitalized_name$().getMap().size();\n"
473 "}\n");
474 printer->Annotate("{", "}", descriptor_);
475 WriteFieldDocComment(printer, descriptor_);
476 printer->Print(
477 variables_,
478 "$deprecation$\n"
479 "@java.lang.Override\n"
480 "public boolean ${$contains$capitalized_name$$}$(\n"
481 " $key_type$ key) {\n"
482 " $key_null_check$\n"
483 " return internalGet$capitalized_name$().getMap().containsKey(key);\n"
484 "}\n");
485 printer->Annotate("{", "}", descriptor_);
486 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
487 printer->Print(variables_,
488 "/**\n"
489 " * Use {@link #get$capitalized_name$Map()} instead.\n"
490 " */\n"
491 "@java.lang.Override\n"
492 "@java.lang.Deprecated\n"
493 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
494 "${$get$capitalized_name$$}$() {\n"
495 " return get$capitalized_name$Map();\n"
496 "}\n");
497 printer->Annotate("{", "}", descriptor_);
498 WriteFieldDocComment(printer, descriptor_);
499 printer->Print(variables_,
500 "@java.lang.Override\n"
501 "$deprecation$\n"
502 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
503 "${$get$capitalized_name$Map$}$() {\n"
504 " return internalGetAdapted$capitalized_name$Map(\n"
505 " internalGet$capitalized_name$().getMap());"
506 "}\n");
507 printer->Annotate("{", "}", descriptor_);
508 WriteFieldDocComment(printer, descriptor_);
509 printer->Print(
510 variables_,
511 "@java.lang.Override\n"
512 "$deprecation$\n"
513 "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
514 " $key_type$ key,\n"
515 " $value_enum_type$ defaultValue) {\n"
516 " $key_null_check$\n"
517 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
518 " internalGet$capitalized_name$().getMap();\n"
519 " return map.containsKey(key)\n"
520 " ? $name$ValueConverter.doForward(map.get(key))\n"
521 " : defaultValue;\n"
522 "}\n");
523 printer->Annotate("{", "}", descriptor_);
524 WriteFieldDocComment(printer, descriptor_);
525 printer->Print(
526 variables_,
527 "@java.lang.Override\n"
528 "$deprecation$\n"
529 "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
530 " $key_type$ key) {\n"
531 " $key_null_check$\n"
532 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
533 " internalGet$capitalized_name$().getMap();\n"
534 " if (!map.containsKey(key)) {\n"
535 " throw new java.lang.IllegalArgumentException();\n"
536 " }\n"
537 " return $name$ValueConverter.doForward(map.get(key));\n"
538 "}\n");
539 printer->Annotate("{", "}", descriptor_);
540 if (SupportUnknownEnumValue(descriptor_->file())) {
541 printer->Print(
542 variables_,
543 "/**\n"
544 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
545 " */\n"
546 "@java.lang.Override\n"
547 "@java.lang.Deprecated\n"
548 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
549 "${$get$capitalized_name$Value$}$() {\n"
550 " return get$capitalized_name$ValueMap();\n"
551 "}\n");
552 printer->Annotate("{", "}", descriptor_);
553 WriteFieldDocComment(printer, descriptor_);
554 printer->Print(
555 variables_,
556 "@java.lang.Override\n"
557 "$deprecation$\n"
558 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
559 "${$get$capitalized_name$ValueMap$}$() {\n"
560 " return internalGet$capitalized_name$().getMap();\n"
561 "}\n");
562 printer->Annotate("{", "}", descriptor_);
563 WriteFieldDocComment(printer, descriptor_);
564 printer->Print(
565 variables_,
566 "@java.lang.Override\n"
567 "$deprecation$\n"
568 "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
569 " $key_type$ key,\n"
570 " $value_type$ defaultValue) {\n"
571 " $key_null_check$\n"
572 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
573 " internalGet$capitalized_name$().getMap();\n"
574 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
575 "}\n");
576 printer->Annotate("{", "}", descriptor_);
577 WriteFieldDocComment(printer, descriptor_);
578 printer->Print(
579 variables_,
580 "@java.lang.Override\n"
581 "$deprecation$\n"
582 "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
583 " $key_type$ key) {\n"
584 " $key_null_check$\n"
585 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
586 " internalGet$capitalized_name$().getMap();\n"
587 " if (!map.containsKey(key)) {\n"
588 " throw new java.lang.IllegalArgumentException();\n"
589 " }\n"
590 " return map.get(key);\n"
591 "}\n");
592 printer->Annotate("{", "}", descriptor_);
593 }
594 } else {
595 printer->Print(variables_,
596 "/**\n"
597 " * Use {@link #get$capitalized_name$Map()} instead.\n"
598 " */\n"
599 "@java.lang.Override\n"
600 "@java.lang.Deprecated\n"
601 "public java.util.Map<$type_parameters$> "
602 "${$get$capitalized_name$$}$() {\n"
603 " return get$capitalized_name$Map();\n"
604 "}\n");
605 printer->Annotate("{", "}", descriptor_);
606 WriteFieldDocComment(printer, descriptor_);
607 printer->Print(variables_,
608 "@java.lang.Override\n"
609 "$deprecation$\n"
610 "public java.util.Map<$type_parameters$> "
611 "${$get$capitalized_name$Map$}$() {\n"
612 " return internalGet$capitalized_name$().getMap();\n"
613 "}\n");
614 printer->Annotate("{", "}", descriptor_);
615 WriteFieldDocComment(printer, descriptor_);
616 printer->Print(
617 variables_,
618 "@java.lang.Override\n"
619 "$deprecation$\n"
620 "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
621 " $key_type$ key,\n"
622 " $value_type$ defaultValue) {\n"
623 " $key_null_check$\n"
624 " java.util.Map<$type_parameters$> map =\n"
625 " internalGet$capitalized_name$().getMap();\n"
626 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
627 "}\n");
628 printer->Annotate("{", "}", descriptor_);
629 WriteFieldDocComment(printer, descriptor_);
630 printer->Print(variables_,
631 "@java.lang.Override\n"
632 "$deprecation$\n"
633 "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
634 " $key_type$ key) {\n"
635 " $key_null_check$\n"
636 " java.util.Map<$type_parameters$> map =\n"
637 " internalGet$capitalized_name$().getMap();\n"
638 " if (!map.containsKey(key)) {\n"
639 " throw new java.lang.IllegalArgumentException();\n"
640 " }\n"
641 " return map.get(key);\n"
642 "}\n");
643 printer->Annotate("{", "}", descriptor_);
644 }
645 }
646
GenerateFieldBuilderInitializationCode(io::Printer * printer) const647 void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode(
648 io::Printer* printer) const {
649 // Nothing to initialize.
650 }
651
GenerateInitializationCode(io::Printer * printer) const652 void ImmutableMapFieldGenerator::GenerateInitializationCode(
653 io::Printer* printer) const {
654 // Nothing to initialize.
655 }
656
GenerateBuilderClearCode(io::Printer * printer) const657 void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
658 io::Printer* printer) const {
659 printer->Print(variables_,
660 "internalGetMutable$capitalized_name$().clear();\n");
661 }
662
GenerateMergingCode(io::Printer * printer) const663 void ImmutableMapFieldGenerator::GenerateMergingCode(
664 io::Printer* printer) const {
665 printer->Print(variables_,
666 "internalGetMutable$capitalized_name$().mergeFrom(\n"
667 " other.internalGet$capitalized_name$());\n");
668 }
669
GenerateBuildingCode(io::Printer * printer) const670 void ImmutableMapFieldGenerator::GenerateBuildingCode(
671 io::Printer* printer) const {
672 printer->Print(variables_,
673 "result.$name$_ = internalGet$capitalized_name$();\n"
674 "result.$name$_.makeImmutable();\n");
675 }
676
GenerateBuilderParsingCode(io::Printer * printer) const677 void ImmutableMapFieldGenerator::GenerateBuilderParsingCode(
678 io::Printer* printer) const {
679 if (!SupportUnknownEnumValue(descriptor_->file()) &&
680 GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
681 printer->Print(
682 variables_,
683 "com.google.protobuf.ByteString bytes = input.readBytes();\n"
684 "com.google.protobuf.MapEntry<$type_parameters$>\n"
685 "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n"
686 "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n"
687 " mergeUnknownLengthDelimitedField($number$, bytes);\n"
688 "} else {\n"
689 " internalGetMutable$capitalized_name$().getMutableMap().put(\n"
690 " $name$__.getKey(), $name$__.getValue());\n"
691 "}\n");
692 } else {
693 printer->Print(
694 variables_,
695 "com.google.protobuf.MapEntry<$type_parameters$>\n"
696 "$name$__ = input.readMessage(\n"
697 " $default_entry$.getParserForType(), extensionRegistry);\n"
698 "internalGetMutable$capitalized_name$().getMutableMap().put(\n"
699 " $name$__.getKey(), $name$__.getValue());\n");
700 }
701 }
702
GenerateSerializationCode(io::Printer * printer) const703 void ImmutableMapFieldGenerator::GenerateSerializationCode(
704 io::Printer* printer) const {
705 printer->Print(variables_,
706 "com.google.protobuf.GeneratedMessage$ver$\n"
707 " .serialize$short_key_type$MapTo(\n"
708 " output,\n"
709 " internalGet$capitalized_name$(),\n"
710 " $default_entry$,\n"
711 " $number$);\n");
712 }
713
GenerateSerializedSizeCode(io::Printer * printer) const714 void ImmutableMapFieldGenerator::GenerateSerializedSizeCode(
715 io::Printer* printer) const {
716 printer->Print(
717 variables_,
718 "for (java.util.Map.Entry<$type_parameters$> entry\n"
719 " : internalGet$capitalized_name$().getMap().entrySet()) {\n"
720 " com.google.protobuf.MapEntry<$type_parameters$>\n"
721 " $name$__ = $default_entry$.newBuilderForType()\n"
722 " .setKey(entry.getKey())\n"
723 " .setValue(entry.getValue())\n"
724 " .build();\n"
725 " size += com.google.protobuf.CodedOutputStream\n"
726 " .computeMessageSize($number$, $name$__);\n"
727 "}\n");
728 }
729
GenerateEqualsCode(io::Printer * printer) const730 void ImmutableMapFieldGenerator::GenerateEqualsCode(
731 io::Printer* printer) const {
732 printer->Print(variables_,
733 "if (!internalGet$capitalized_name$().equals(\n"
734 " other.internalGet$capitalized_name$())) return false;\n");
735 }
736
GenerateHashCode(io::Printer * printer) const737 void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const {
738 printer->Print(
739 variables_,
740 "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
741 " hash = (37 * hash) + $constant_name$;\n"
742 " hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
743 "}\n");
744 }
745
GetBoxedType() const746 std::string ImmutableMapFieldGenerator::GetBoxedType() const {
747 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
748 }
749
750 } // namespace java
751 } // namespace compiler
752 } // namespace protobuf
753 } // namespace google
754