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_lite.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
83 ClassNameResolver* name_resolver = context->GetNameResolver();
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 (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
93 (*variables)["key_wire_type"] = WireType(key);
94 (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
95 // We use `x.getClass()` as a null check because it generates less bytecode
96 // than an `if (x == null) { throw ... }` statement.
97 (*variables)["key_null_check"] =
98 IsReferenceType(keyJavaType) ? "key.getClass();" : "";
99 (*variables)["value_null_check"] =
100 IsReferenceType(valueJavaType) ? "value.getClass();" : "";
101
102 if (GetJavaType(value) == JAVATYPE_ENUM) {
103 // We store enums as Integers internally.
104 (*variables)["value_type"] = "int";
105 (*variables)["boxed_value_type"] = "java.lang.Integer";
106 (*variables)["value_wire_type"] = WireType(value);
107 (*variables)["value_default_value"] =
108 DefaultValue(value, true, name_resolver) + ".getNumber()";
109
110 (*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
111
112 if (SupportUnknownEnumValue(descriptor->file())) {
113 // Map unknown values to a special UNRECOGNIZED value if supported.
114 (*variables)["unrecognized_value"] =
115 (*variables)["value_enum_type"] + ".UNRECOGNIZED";
116 } else {
117 // Map unknown values to the default value if we don't have UNRECOGNIZED.
118 (*variables)["unrecognized_value"] =
119 DefaultValue(value, true, name_resolver);
120 }
121 } else {
122 (*variables)["value_type"] = TypeName(value, name_resolver, false);
123 (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
124 (*variables)["value_wire_type"] = WireType(value);
125 (*variables)["value_default_value"] =
126 DefaultValue(value, true, name_resolver);
127 }
128 (*variables)["type_parameters"] =
129 (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
130 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
131 // by the proto compiler
132 (*variables)["deprecation"] =
133 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
134
135 (*variables)["default_entry"] =
136 (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
137 }
138
139 } // namespace
140
ImmutableMapFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)141 ImmutableMapFieldLiteGenerator::ImmutableMapFieldLiteGenerator(
142 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
143 : descriptor_(descriptor),
144 context_(context),
145 name_resolver_(context->GetNameResolver()) {
146 SetMessageVariables(descriptor, messageBitIndex, 0,
147 context->GetFieldGeneratorInfo(descriptor), context,
148 &variables_);
149 }
150
~ImmutableMapFieldLiteGenerator()151 ImmutableMapFieldLiteGenerator::~ImmutableMapFieldLiteGenerator() {}
152
GetNumBitsForMessage() const153 int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { return 0; }
154
GenerateInterfaceMembers(io::Printer * printer) const155 void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers(
156 io::Printer* printer) const {
157 WriteFieldDocComment(printer, descriptor_);
158 printer->Print(variables_,
159 "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
160 printer->Annotate("{", "}", descriptor_);
161 WriteFieldDocComment(printer, descriptor_);
162 printer->Print(variables_,
163 "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
164 " $key_type$ key);\n");
165 printer->Annotate("{", "}", descriptor_);
166 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
167 printer->Print(variables_,
168 "/**\n"
169 " * Use {@link #get$capitalized_name$Map()} instead.\n"
170 " */\n"
171 "@java.lang.Deprecated\n"
172 "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
173 "${$get$capitalized_name$$}$();\n");
174 printer->Annotate("{", "}", descriptor_);
175 WriteFieldDocComment(printer, descriptor_);
176 printer->Print(
177 variables_,
178 "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
179 "${$get$capitalized_name$Map$}$();\n");
180 printer->Annotate("{", "}", descriptor_);
181 WriteFieldDocComment(printer, descriptor_);
182 printer->Print(
183 variables_,
184 "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
185 " $key_type$ key,\n"
186 " $value_enum_type$ defaultValue);\n");
187 printer->Annotate("{", "}", descriptor_);
188 WriteFieldDocComment(printer, descriptor_);
189 printer->Print(
190 variables_,
191 "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
192 " $key_type$ key);\n");
193 printer->Annotate("{", "}", descriptor_);
194 if (SupportUnknownEnumValue(descriptor_->file())) {
195 printer->Print(
196 variables_,
197 "/**\n"
198 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
199 " */\n"
200 "@java.lang.Deprecated\n"
201 "java.util.Map<$type_parameters$>\n"
202 "${$get$capitalized_name$Value$}$();\n");
203 printer->Annotate("{", "}", descriptor_);
204 WriteFieldDocComment(printer, descriptor_);
205 printer->Print(variables_,
206 "$deprecation$java.util.Map<$type_parameters$>\n"
207 "${$get$capitalized_name$ValueMap$}$();\n");
208 printer->Annotate("{", "}", descriptor_);
209 WriteFieldDocComment(printer, descriptor_);
210 printer->Print(variables_,
211 "$deprecation$\n"
212 "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
213 " $key_type$ key,\n"
214 " $value_type$ defaultValue);\n");
215 printer->Annotate("{", "}", descriptor_);
216 WriteFieldDocComment(printer, descriptor_);
217 printer->Print(variables_,
218 "$deprecation$\n"
219 "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
220 " $key_type$ key);\n");
221 printer->Annotate("{", "}", descriptor_);
222 }
223 } else {
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<$type_parameters$>\n"
230 "${$get$capitalized_name$$}$();\n");
231 printer->Annotate("{", "}", descriptor_);
232 WriteFieldDocComment(printer, descriptor_);
233 printer->Print(variables_,
234 "$deprecation$java.util.Map<$type_parameters$>\n"
235 "${$get$capitalized_name$Map$}$();\n");
236 printer->Annotate("{", "}", descriptor_);
237 WriteFieldDocComment(printer, descriptor_);
238 printer->Print(variables_,
239 "$deprecation$\n"
240 "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
241 " $key_type$ key,\n"
242 " $value_type$ defaultValue);\n");
243 printer->Annotate("{", "}", descriptor_);
244 WriteFieldDocComment(printer, descriptor_);
245 printer->Print(variables_,
246 "$deprecation$\n"
247 "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
248 " $key_type$ key);\n");
249 printer->Annotate("{", "}", descriptor_);
250 }
251 }
252
GenerateMembers(io::Printer * printer) const253 void ImmutableMapFieldLiteGenerator::GenerateMembers(
254 io::Printer* printer) const {
255 printer->Print(
256 variables_,
257 "private static final class $capitalized_name$DefaultEntryHolder {\n"
258 " static final com.google.protobuf.MapEntryLite<\n"
259 " $type_parameters$> defaultEntry =\n"
260 " com.google.protobuf.MapEntryLite\n"
261 " .<$type_parameters$>newDefaultInstance(\n"
262 " $key_wire_type$,\n"
263 " $key_default_value$,\n"
264 " $value_wire_type$,\n"
265 " $value_default_value$);\n"
266 "}\n");
267 printer->Print(variables_,
268 "private com.google.protobuf.MapFieldLite<\n"
269 " $type_parameters$> $name$_ =\n"
270 " com.google.protobuf.MapFieldLite.emptyMapField();\n"
271 "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
272 "internalGet$capitalized_name$() {\n"
273 " return $name$_;\n"
274 "}\n"
275 "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
276 "internalGetMutable$capitalized_name$() {\n"
277 " if (!$name$_.isMutable()) {\n"
278 " $name$_ = $name$_.mutableCopy();\n"
279 " }\n"
280 " return $name$_;\n"
281 "}\n");
282 printer->Print(variables_,
283 "@java.lang.Override\n"
284 "$deprecation$\n"
285 "public int ${$get$capitalized_name$Count$}$() {\n"
286 " return internalGet$capitalized_name$().size();\n"
287 "}\n");
288 printer->Annotate("{", "}", descriptor_);
289 WriteFieldDocComment(printer, descriptor_);
290 printer->Print(variables_,
291 "@java.lang.Override\n"
292 "$deprecation$\n"
293 "public boolean ${$contains$capitalized_name$$}$(\n"
294 " $key_type$ key) {\n"
295 " $key_null_check$\n"
296 " return internalGet$capitalized_name$().containsKey(key);\n"
297 "}\n");
298 printer->Annotate("{", "}", descriptor_);
299 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
300 printer->Print(
301 variables_,
302 "private static final\n"
303 "com.google.protobuf.Internal.MapAdapter.Converter<\n"
304 " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
305 " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
306 " $value_enum_type$.internalGetValueMap(),\n"
307 " $unrecognized_value$);\n");
308 printer->Print(variables_,
309 "/**\n"
310 " * Use {@link #get$capitalized_name$Map()} instead.\n"
311 " */\n"
312 "@java.lang.Deprecated\n"
313 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
314 "${$get$capitalized_name$$}$() {\n"
315 " return get$capitalized_name$Map();\n"
316 "}\n");
317 printer->Annotate("{", "}", descriptor_);
318 WriteFieldDocComment(printer, descriptor_);
319 printer->Print(
320 variables_,
321 "@java.lang.Override\n"
322 "$deprecation$\n"
323 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
324 "${$get$capitalized_name$Map$}$() {\n"
325 " return java.util.Collections.unmodifiableMap(\n"
326 " new com.google.protobuf.Internal.MapAdapter<\n"
327 " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
328 " internalGet$capitalized_name$(),\n"
329 " $name$ValueConverter));\n"
330 "}\n");
331 printer->Annotate("{", "}", descriptor_);
332 WriteFieldDocComment(printer, descriptor_);
333 printer->Print(
334 variables_,
335 "@java.lang.Override\n"
336 "$deprecation$\n"
337 "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
338 " $key_type$ key,\n"
339 " $value_enum_type$ defaultValue) {\n"
340 " $key_null_check$\n"
341 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
342 " internalGet$capitalized_name$();\n"
343 " return map.containsKey(key)\n"
344 " ? $name$ValueConverter.doForward(map.get(key))\n"
345 " : defaultValue;\n"
346 "}\n");
347 printer->Annotate("{", "}", descriptor_);
348 WriteFieldDocComment(printer, descriptor_);
349 printer->Print(
350 variables_,
351 "@java.lang.Override\n"
352 "$deprecation$\n"
353 "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
354 " $key_type$ key) {\n"
355 " $key_null_check$\n"
356 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
357 " internalGet$capitalized_name$();\n"
358 " if (!map.containsKey(key)) {\n"
359 " throw new java.lang.IllegalArgumentException();\n"
360 " }\n"
361 " return $name$ValueConverter.doForward(map.get(key));\n"
362 "}\n");
363 printer->Annotate("{", "}", descriptor_);
364 if (SupportUnknownEnumValue(descriptor_->file())) {
365 printer->Print(
366 variables_,
367 "/**\n"
368 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
369 " */\n"
370 "@java.lang.Override\n"
371 "@java.lang.Deprecated\n"
372 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
373 "${$get$capitalized_name$Value$}$() {\n"
374 " return get$capitalized_name$ValueMap();\n"
375 "}\n");
376 printer->Annotate("{", "}", descriptor_);
377 WriteFieldDocComment(printer, descriptor_);
378 printer->Print(
379 variables_,
380 "@java.lang.Override\n"
381 "$deprecation$\n"
382 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
383 "${$get$capitalized_name$ValueMap$}$() {\n"
384 " return java.util.Collections.unmodifiableMap(\n"
385 " internalGet$capitalized_name$());\n"
386 "}\n");
387 printer->Annotate("{", "}", descriptor_);
388 WriteFieldDocComment(printer, descriptor_);
389 printer->Print(
390 variables_,
391 "@java.lang.Override\n"
392 "$deprecation$\n"
393 "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
394 " $key_type$ key,\n"
395 " $value_type$ defaultValue) {\n"
396 " $key_null_check$\n"
397 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
398 " internalGet$capitalized_name$();\n"
399 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
400 "}\n");
401 printer->Annotate("{", "}", descriptor_);
402 WriteFieldDocComment(printer, descriptor_);
403 printer->Print(
404 variables_,
405 "@java.lang.Override\n"
406 "$deprecation$\n"
407 "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
408 " $key_type$ key) {\n"
409 " $key_null_check$\n"
410 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
411 " internalGet$capitalized_name$();\n"
412 " if (!map.containsKey(key)) {\n"
413 " throw new java.lang.IllegalArgumentException();\n"
414 " }\n"
415 " return map.get(key);\n"
416 "}\n");
417 printer->Annotate("{", "}", descriptor_);
418 }
419 } else {
420 printer->Print(variables_,
421 "/**\n"
422 " * Use {@link #get$capitalized_name$Map()} instead.\n"
423 " */\n"
424 "@java.lang.Override\n"
425 "@java.lang.Deprecated\n"
426 "public java.util.Map<$type_parameters$> "
427 "${$get$capitalized_name$$}$() {\n"
428 " return get$capitalized_name$Map();\n"
429 "}\n");
430 printer->Annotate("{", "}", descriptor_);
431 WriteFieldDocComment(printer, descriptor_);
432 printer->Print(variables_,
433 "@java.lang.Override\n"
434 "$deprecation$\n"
435 "public java.util.Map<$type_parameters$> "
436 "${$get$capitalized_name$Map$}$() {\n"
437 " return java.util.Collections.unmodifiableMap(\n"
438 " internalGet$capitalized_name$());\n"
439 "}\n");
440 printer->Annotate("{", "}", descriptor_);
441 WriteFieldDocComment(printer, descriptor_);
442 printer->Print(
443 variables_,
444 "@java.lang.Override\n"
445 "$deprecation$\n"
446 "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
447 " $key_type$ key,\n"
448 " $value_type$ defaultValue) {\n"
449 " $key_null_check$\n"
450 " java.util.Map<$type_parameters$> map =\n"
451 " internalGet$capitalized_name$();\n"
452 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
453 "}\n");
454 printer->Annotate("{", "}", descriptor_);
455 WriteFieldDocComment(printer, descriptor_);
456 printer->Print(variables_,
457 "@java.lang.Override\n"
458 "$deprecation$\n"
459 "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
460 " $key_type$ key) {\n"
461 " $key_null_check$\n"
462 " java.util.Map<$type_parameters$> map =\n"
463 " internalGet$capitalized_name$();\n"
464 " if (!map.containsKey(key)) {\n"
465 " throw new java.lang.IllegalArgumentException();\n"
466 " }\n"
467 " return map.get(key);\n"
468 "}\n");
469 printer->Annotate("{", "}", descriptor_);
470 }
471
472 // Generate private setters for the builder to proxy into.
473 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
474 WriteFieldDocComment(printer, descriptor_);
475 printer->Print(
476 variables_,
477 "private java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
478 "getMutable$capitalized_name$Map() {\n"
479 " return new com.google.protobuf.Internal.MapAdapter<\n"
480 " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
481 " internalGetMutable$capitalized_name$(),\n"
482 " $name$ValueConverter);\n"
483 "}\n");
484 if (SupportUnknownEnumValue(descriptor_->file())) {
485 WriteFieldDocComment(printer, descriptor_);
486 printer->Print(
487 variables_,
488 "private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
489 "getMutable$capitalized_name$ValueMap() {\n"
490 " return internalGetMutable$capitalized_name$();\n"
491 "}\n");
492 }
493 } else {
494 WriteFieldDocComment(printer, descriptor_);
495 printer->Print(variables_,
496 "private java.util.Map<$type_parameters$>\n"
497 "getMutable$capitalized_name$Map() {\n"
498 " return internalGetMutable$capitalized_name$();\n"
499 "}\n");
500 }
501 }
502
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const503 void ImmutableMapFieldLiteGenerator::GenerateFieldInfo(
504 io::Printer* printer, std::vector<uint16>* output) const {
505 WriteIntToUtf16CharSequence(descriptor_->number(), output);
506 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
507 output);
508 printer->Print(variables_,
509 "\"$name$_\",\n"
510 "$default_entry$,\n");
511 if (!SupportUnknownEnumValue(descriptor_) &&
512 GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
513 PrintEnumVerifierLogic(printer, ValueField(descriptor_), variables_,
514 /*var_name=*/"$value_enum_type$",
515 /*terminating_string=*/",\n",
516 /*enforce_lite=*/context_->EnforceLite());
517 }
518 }
519
GenerateBuilderMembers(io::Printer * printer) const520 void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers(
521 io::Printer* printer) const {
522 printer->Print(variables_,
523 "@java.lang.Override\n"
524 "$deprecation$\n"
525 "public int ${$get$capitalized_name$Count$}$() {\n"
526 " return instance.get$capitalized_name$Map().size();\n"
527 "}\n");
528 printer->Annotate("{", "}", descriptor_);
529 WriteFieldDocComment(printer, descriptor_);
530 printer->Print(
531 variables_,
532 "@java.lang.Override\n"
533 "$deprecation$\n"
534 "public boolean ${$contains$capitalized_name$$}$(\n"
535 " $key_type$ key) {\n"
536 " $key_null_check$\n"
537 " return instance.get$capitalized_name$Map().containsKey(key);\n"
538 "}\n");
539 printer->Annotate("{", "}", descriptor_);
540 printer->Print(variables_,
541 "$deprecation$\n"
542 "public Builder ${$clear$capitalized_name$$}$() {\n"
543 " copyOnWrite();\n"
544 " instance.getMutable$capitalized_name$Map().clear();\n"
545 " return this;\n"
546 "}\n");
547 printer->Annotate("{", "}", descriptor_);
548 WriteFieldDocComment(printer, descriptor_);
549 printer->Print(variables_,
550 "$deprecation$\n"
551 "public Builder ${$remove$capitalized_name$$}$(\n"
552 " $key_type$ key) {\n"
553 " $key_null_check$\n"
554 " copyOnWrite();\n"
555 " instance.getMutable$capitalized_name$Map().remove(key);\n"
556 " return this;\n"
557 "}\n");
558 printer->Annotate("{", "}", descriptor_);
559 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
560 printer->Print(variables_,
561 "/**\n"
562 " * Use {@link #get$capitalized_name$Map()} instead.\n"
563 " */\n"
564 "@java.lang.Deprecated\n"
565 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
566 "${$get$capitalized_name$$}$() {\n"
567 " return get$capitalized_name$Map();\n"
568 "}\n");
569 printer->Annotate("{", "}", descriptor_);
570 WriteFieldDocComment(printer, descriptor_);
571 printer->Print(variables_,
572 "@java.lang.Override\n"
573 "$deprecation$\n"
574 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
575 "${$get$capitalized_name$Map$}$() {\n"
576 " return java.util.Collections.unmodifiableMap(\n"
577 " instance.get$capitalized_name$Map());\n"
578 "}\n");
579 printer->Annotate("{", "}", descriptor_);
580 WriteFieldDocComment(printer, descriptor_);
581 printer->Print(
582 variables_,
583 "@java.lang.Override\n"
584 "$deprecation$\n"
585 "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
586 " $key_type$ key,\n"
587 " $value_enum_type$ defaultValue) {\n"
588 " $key_null_check$\n"
589 " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
590 " instance.get$capitalized_name$Map();\n"
591 " return map.containsKey(key)\n"
592 " ? map.get(key)\n"
593 " : defaultValue;\n"
594 "}\n");
595 printer->Annotate("{", "}", descriptor_);
596 WriteFieldDocComment(printer, descriptor_);
597 printer->Print(
598 variables_,
599 "@java.lang.Override\n"
600 "$deprecation$\n"
601 "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
602 " $key_type$ key) {\n"
603 " $key_null_check$\n"
604 " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
605 " instance.get$capitalized_name$Map();\n"
606 " if (!map.containsKey(key)) {\n"
607 " throw new java.lang.IllegalArgumentException();\n"
608 " }\n"
609 " return map.get(key);\n"
610 "}\n");
611 printer->Annotate("{", "}", descriptor_);
612 WriteFieldDocComment(printer, descriptor_);
613 printer->Print(
614 variables_,
615 "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
616 " $key_type$ key,\n"
617 " $value_enum_type$ value) {\n"
618 " $key_null_check$\n"
619 " $value_null_check$\n"
620 " copyOnWrite();\n"
621 " instance.getMutable$capitalized_name$Map().put(key, value);\n"
622 " return this;\n"
623 "}\n");
624 printer->Annotate("{", "}", descriptor_);
625 WriteFieldDocComment(printer, descriptor_);
626 printer->Print(
627 variables_,
628 "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
629 " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
630 " copyOnWrite();\n"
631 " instance.getMutable$capitalized_name$Map().putAll(values);\n"
632 " return this;\n"
633 "}\n");
634 printer->Annotate("{", "}", descriptor_);
635 if (SupportUnknownEnumValue(descriptor_->file())) {
636 printer->Print(
637 variables_,
638 "/**\n"
639 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
640 " */\n"
641 "@java.lang.Override\n"
642 "@java.lang.Deprecated\n"
643 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
644 "${$get$capitalized_name$Value$}$() {\n"
645 " return get$capitalized_name$ValueMap();\n"
646 "}\n");
647 printer->Annotate("{", "}", descriptor_);
648 WriteFieldDocComment(printer, descriptor_);
649 printer->Print(
650 variables_,
651 "@java.lang.Override\n"
652 "$deprecation$\n"
653 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
654 "${$get$capitalized_name$ValueMap$}$() {\n"
655 " return java.util.Collections.unmodifiableMap(\n"
656 " instance.get$capitalized_name$ValueMap());\n"
657 "}\n");
658 printer->Annotate("{", "}", descriptor_);
659 WriteFieldDocComment(printer, descriptor_);
660 printer->Print(
661 variables_,
662 "@java.lang.Override\n"
663 "$deprecation$\n"
664 "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
665 " $key_type$ key,\n"
666 " $value_type$ defaultValue) {\n"
667 " $key_null_check$\n"
668 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
669 " instance.get$capitalized_name$ValueMap();\n"
670 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
671 "}\n");
672 printer->Annotate("{", "}", descriptor_);
673 WriteFieldDocComment(printer, descriptor_);
674 printer->Print(
675 variables_,
676 "@java.lang.Override\n"
677 "$deprecation$\n"
678 "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
679 " $key_type$ key) {\n"
680 " $key_null_check$\n"
681 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
682 " instance.get$capitalized_name$ValueMap();\n"
683 " if (!map.containsKey(key)) {\n"
684 " throw new java.lang.IllegalArgumentException();\n"
685 " }\n"
686 " return map.get(key);\n"
687 "}\n");
688 printer->Annotate("{", "}", descriptor_);
689 WriteFieldDocComment(printer, descriptor_);
690 printer->Print(
691 variables_,
692 "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
693 " $key_type$ key,\n"
694 " $value_type$ value) {\n"
695 " $key_null_check$\n"
696 " copyOnWrite();\n"
697 " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n"
698 " return this;\n"
699 "}\n");
700 printer->Annotate("{", "}", descriptor_);
701 WriteFieldDocComment(printer, descriptor_);
702 printer->Print(
703 variables_,
704 "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
705 " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
706 " copyOnWrite();\n"
707 " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n"
708 " return this;\n"
709 "}\n");
710 printer->Annotate("{", "}", descriptor_);
711 }
712 } else {
713 printer->Print(variables_,
714 "/**\n"
715 " * Use {@link #get$capitalized_name$Map()} instead.\n"
716 " */\n"
717 "@java.lang.Override\n"
718 "@java.lang.Deprecated\n"
719 "public java.util.Map<$type_parameters$> "
720 "${$get$capitalized_name$$}$() {\n"
721 " return get$capitalized_name$Map();\n"
722 "}\n");
723 printer->Annotate("{", "}", descriptor_);
724 WriteFieldDocComment(printer, descriptor_);
725 printer->Print(variables_,
726 "@java.lang.Override\n"
727 "$deprecation$"
728 "public java.util.Map<$type_parameters$> "
729 "${$get$capitalized_name$Map$}$() {\n"
730 " return java.util.Collections.unmodifiableMap(\n"
731 " instance.get$capitalized_name$Map());\n"
732 "}\n");
733 printer->Annotate("{", "}", descriptor_);
734 WriteFieldDocComment(printer, descriptor_);
735 printer->Print(
736 variables_,
737 "@java.lang.Override\n"
738 "$deprecation$\n"
739 "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
740 " $key_type$ key,\n"
741 " $value_type$ defaultValue) {\n"
742 " $key_null_check$\n"
743 " java.util.Map<$type_parameters$> map =\n"
744 " instance.get$capitalized_name$Map();\n"
745 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
746 "}\n");
747 printer->Annotate("{", "}", descriptor_);
748 WriteFieldDocComment(printer, descriptor_);
749 printer->Print(variables_,
750 "@java.lang.Override\n"
751 "$deprecation$\n"
752 "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
753 " $key_type$ key) {\n"
754 " $key_null_check$\n"
755 " java.util.Map<$type_parameters$> map =\n"
756 " instance.get$capitalized_name$Map();\n"
757 " if (!map.containsKey(key)) {\n"
758 " throw new java.lang.IllegalArgumentException();\n"
759 " }\n"
760 " return map.get(key);\n"
761 "}\n");
762 printer->Annotate("{", "}", descriptor_);
763 WriteFieldDocComment(printer, descriptor_);
764 printer->Print(
765 variables_,
766 "$deprecation$"
767 "public Builder ${$put$capitalized_name$$}$(\n"
768 " $key_type$ key,\n"
769 " $value_type$ value) {\n"
770 " $key_null_check$\n"
771 " $value_null_check$\n"
772 " copyOnWrite();\n"
773 " instance.getMutable$capitalized_name$Map().put(key, value);\n"
774 " return this;\n"
775 "}\n");
776 printer->Annotate("{", "}", descriptor_);
777 WriteFieldDocComment(printer, descriptor_);
778 printer->Print(
779 variables_,
780 "$deprecation$"
781 "public Builder ${$putAll$capitalized_name$$}$(\n"
782 " java.util.Map<$type_parameters$> values) {\n"
783 " copyOnWrite();\n"
784 " instance.getMutable$capitalized_name$Map().putAll(values);\n"
785 " return this;\n"
786 "}\n");
787 printer->Annotate("{", "}", descriptor_);
788 }
789 }
790
GenerateInitializationCode(io::Printer * printer) const791 void ImmutableMapFieldLiteGenerator::GenerateInitializationCode(
792 io::Printer* printer) const {
793 // Nothing to initialize.
794 }
795
GetBoxedType() const796 std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const {
797 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
798 }
799
800 } // namespace java
801 } // namespace compiler
802 } // namespace protobuf
803 } // namespace google
804