| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 #include <google/protobuf/compiler/java/java_name_resolver.h> | 42 #include <google/protobuf/compiler/java/java_name_resolver.h> |
| 43 #include <google/protobuf/io/printer.h> | 43 #include <google/protobuf/io/printer.h> |
| 44 #include <google/protobuf/descriptor.pb.h> | 44 #include <google/protobuf/descriptor.pb.h> |
| 45 #include <google/protobuf/stubs/strutil.h> | 45 #include <google/protobuf/stubs/strutil.h> |
| 46 | 46 |
| 47 namespace google { | 47 namespace google { |
| 48 namespace protobuf { | 48 namespace protobuf { |
| 49 namespace compiler { | 49 namespace compiler { |
| 50 namespace java { | 50 namespace java { |
| 51 | 51 |
| 52 namespace { |
| 53 bool EnumHasCustomOptions(const EnumDescriptor* descriptor) { |
| 54 if (descriptor->options().unknown_fields().field_count() > 0) return true; |
| 55 for (int i = 0; i < descriptor->value_count(); ++i) { |
| 56 const EnumValueDescriptor* value = descriptor->value(i); |
| 57 if (value->options().unknown_fields().field_count() > 0) return true; |
| 58 } |
| 59 return false; |
| 60 } |
| 61 } // namespace |
| 62 |
| 52 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, | 63 EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, |
| 53 bool immutable_api, | 64 bool immutable_api, |
| 54 Context* context) | 65 Context* context) |
| 55 : descriptor_(descriptor), immutable_api_(immutable_api), | 66 : descriptor_(descriptor), immutable_api_(immutable_api), |
| 56 context_(context), | 67 context_(context), |
| 57 name_resolver_(context->GetNameResolver()) { | 68 name_resolver_(context->GetNameResolver()) { |
| 58 for (int i = 0; i < descriptor_->value_count(); i++) { | 69 for (int i = 0; i < descriptor_->value_count(); i++) { |
| 59 const EnumValueDescriptor* value = descriptor_->value(i); | 70 const EnumValueDescriptor* value = descriptor_->value(i); |
| 60 const EnumValueDescriptor* canonical_value = | 71 const EnumValueDescriptor* canonical_value = |
| 61 descriptor_->FindValueByNumber(value->number()); | 72 descriptor_->FindValueByNumber(value->number()); |
| 62 | 73 |
| 63 if (value == canonical_value) { | 74 if (value == canonical_value) { |
| 64 canonical_values_.push_back(value); | 75 canonical_values_.push_back(value); |
| 65 } else { | 76 } else { |
| 66 Alias alias; | 77 Alias alias; |
| 67 alias.value = value; | 78 alias.value = value; |
| 68 alias.canonical_value = canonical_value; | 79 alias.canonical_value = canonical_value; |
| 69 aliases_.push_back(alias); | 80 aliases_.push_back(alias); |
| 70 } | 81 } |
| 71 } | 82 } |
| 72 } | 83 } |
| 73 | 84 |
| 74 EnumGenerator::~EnumGenerator() {} | 85 EnumGenerator::~EnumGenerator() {} |
| 75 | 86 |
| 76 void EnumGenerator::Generate(io::Printer* printer) { | 87 void EnumGenerator::Generate(io::Printer* printer) { |
| 77 WriteEnumDocComment(printer, descriptor_); | 88 WriteEnumDocComment(printer, descriptor_); |
| 78 MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); | |
| 79 printer->Print( | 89 printer->Print( |
| 80 "public enum $classname$\n" | 90 "public enum $classname$\n" |
| 81 " implements com.google.protobuf.ProtocolMessageEnum {\n", | 91 " implements com.google.protobuf.ProtocolMessageEnum {\n", |
| 82 "classname", descriptor_->name()); | 92 "classname", descriptor_->name()); |
| 83 printer->Annotate("classname", descriptor_); | |
| 84 printer->Indent(); | 93 printer->Indent(); |
| 85 | 94 |
| 86 bool ordinal_is_index = true; | 95 bool ordinal_is_index = true; |
| 87 string index_text = "ordinal()"; | 96 string index_text = "ordinal()"; |
| 88 for (int i = 0; i < canonical_values_.size(); i++) { | 97 for (int i = 0; i < canonical_values_.size(); i++) { |
| 89 if (canonical_values_[i]->index() != i) { | 98 if (canonical_values_[i]->index() != i) { |
| 90 ordinal_is_index = false; | 99 ordinal_is_index = false; |
| 91 index_text = "index"; | 100 index_text = "index"; |
| 92 break; | 101 break; |
| 93 } | 102 } |
| 94 } | 103 } |
| 95 | 104 |
| 96 for (int i = 0; i < canonical_values_.size(); i++) { | 105 for (int i = 0; i < canonical_values_.size(); i++) { |
| 97 std::map<string, string> vars; | 106 map<string, string> vars; |
| 98 vars["name"] = canonical_values_[i]->name(); | 107 vars["name"] = canonical_values_[i]->name(); |
| 99 vars["index"] = SimpleItoa(canonical_values_[i]->index()); | 108 vars["index"] = SimpleItoa(canonical_values_[i]->index()); |
| 100 vars["number"] = SimpleItoa(canonical_values_[i]->number()); | 109 vars["number"] = SimpleItoa(canonical_values_[i]->number()); |
| 101 WriteEnumValueDocComment(printer, canonical_values_[i]); | 110 WriteEnumValueDocComment(printer, canonical_values_[i]); |
| 102 if (canonical_values_[i]->options().deprecated()) { | 111 if (canonical_values_[i]->options().deprecated()) { |
| 103 printer->Print("@java.lang.Deprecated\n"); | 112 printer->Print("@java.lang.Deprecated\n"); |
| 104 } | 113 } |
| 105 if (ordinal_is_index) { | 114 if (ordinal_is_index) { |
| 106 printer->Print(vars, | 115 printer->Print(vars, |
| 107 "$name$($number$),\n"); | 116 "$name$($number$),\n"); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 119 } | 128 } |
| 120 } | 129 } |
| 121 | 130 |
| 122 printer->Print( | 131 printer->Print( |
| 123 ";\n" | 132 ";\n" |
| 124 "\n"); | 133 "\n"); |
| 125 | 134 |
| 126 // ----------------------------------------------------------------- | 135 // ----------------------------------------------------------------- |
| 127 | 136 |
| 128 for (int i = 0; i < aliases_.size(); i++) { | 137 for (int i = 0; i < aliases_.size(); i++) { |
| 129 std::map<string, string> vars; | 138 map<string, string> vars; |
| 130 vars["classname"] = descriptor_->name(); | 139 vars["classname"] = descriptor_->name(); |
| 131 vars["name"] = aliases_[i].value->name(); | 140 vars["name"] = aliases_[i].value->name(); |
| 132 vars["canonical_name"] = aliases_[i].canonical_value->name(); | 141 vars["canonical_name"] = aliases_[i].canonical_value->name(); |
| 133 WriteEnumValueDocComment(printer, aliases_[i].value); | 142 WriteEnumValueDocComment(printer, aliases_[i].value); |
| 134 printer->Print(vars, | 143 printer->Print(vars, |
| 135 "public static final $classname$ $name$ = $canonical_name$;\n"); | 144 "public static final $classname$ $name$ = $canonical_name$;\n"); |
| 136 } | 145 } |
| 137 | 146 |
| 138 for (int i = 0; i < descriptor_->value_count(); i++) { | 147 for (int i = 0; i < descriptor_->value_count(); i++) { |
| 139 std::map<string, string> vars; | 148 map<string, string> vars; |
| 140 vars["name"] = descriptor_->value(i)->name(); | 149 vars["name"] = descriptor_->value(i)->name(); |
| 141 vars["number"] = SimpleItoa(descriptor_->value(i)->number()); | 150 vars["number"] = SimpleItoa(descriptor_->value(i)->number()); |
| 142 WriteEnumValueDocComment(printer, descriptor_->value(i)); | 151 WriteEnumValueDocComment(printer, descriptor_->value(i)); |
| 143 printer->Print(vars, | 152 printer->Print(vars, |
| 144 "public static final int $name$_VALUE = $number$;\n"); | 153 "public static final int $name$_VALUE = $number$;\n"); |
| 145 } | 154 } |
| 146 printer->Print("\n"); | 155 printer->Print("\n"); |
| 147 | 156 |
| 148 // ----------------------------------------------------------------- | 157 // ----------------------------------------------------------------- |
| 149 | 158 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 " return getDescriptor();\n" | 234 " return getDescriptor();\n" |
| 226 "}\n" | 235 "}\n" |
| 227 "public static final com.google.protobuf.Descriptors.EnumDescriptor\n" | 236 "public static final com.google.protobuf.Descriptors.EnumDescriptor\n" |
| 228 " getDescriptor() {\n", | 237 " getDescriptor() {\n", |
| 229 "index_text", index_text); | 238 "index_text", index_text); |
| 230 | 239 |
| 231 // TODO(kenton): Cache statically? Note that we can't access descriptors | 240 // TODO(kenton): Cache statically? Note that we can't access descriptors |
| 232 // at module init time because it wouldn't work with descriptor.proto, but | 241 // at module init time because it wouldn't work with descriptor.proto, but |
| 233 // we can cache the value the first time getDescriptor() is called. | 242 // we can cache the value the first time getDescriptor() is called. |
| 234 if (descriptor_->containing_type() == NULL) { | 243 if (descriptor_->containing_type() == NULL) { |
| 235 // The class generated for the File fully populates the descriptor with | 244 if (!MultipleJavaFiles(descriptor_->file(), immutable_api_)) { |
| 236 // extensions in both the mutable and immutable cases. (In the mutable api | 245 printer->Print( |
| 237 // this is accomplished by attempting to load the immutable outer class). | 246 " return $file$.getDescriptor().getEnumTypes().get($index$);\n", |
| 238 printer->Print( | 247 "file", name_resolver_->GetClassName(descriptor_->file(), |
| 239 " return $file$.getDescriptor().getEnumTypes().get($index$);\n", | 248 immutable_api_), |
| 240 "file", name_resolver_->GetClassName(descriptor_->file(), | 249 "index", SimpleItoa(descriptor_->index())); |
| 241 immutable_api_), | 250 } else { |
| 242 "index", SimpleItoa(descriptor_->index())); | 251 printer->Indent(); |
| 252 if (EnumHasCustomOptions(descriptor_)) { |
| 253 // We need to load the immutable classes in order to parse custom |
| 254 // options. However, since file level enums (no outer class) are |
| 255 // shared by immutable code and mutable code, the immutable classes |
| 256 // may not exist. So we try to use Java reflection to retrieve the |
| 257 // descriptor from immutable classes. |
| 258 printer->Print( |
| 259 "try {\n" |
| 260 " java.lang.Class immutableFileClass =\n" |
| 261 " java.lang.Class.forName(\"$immutable_file_class_name$\");\n" |
| 262 " @java.lang.SuppressWarnings(\"unchecked\")\n" |
| 263 " java.lang.reflect.Method m =\n" |
| 264 " immutableFileClass.getMethod(\"getDescriptor\");\n" |
| 265 " com.google.protobuf.Descriptors.FileDescriptor file =\n" |
| 266 " (com.google.protobuf.Descriptors.FileDescriptor)\n" |
| 267 " m.invoke(immutableFileClass);\n" |
| 268 " return file.getEnumTypes().get($index$);\n" |
| 269 "} catch (java.lang.Exception e) {\n" |
| 270 // Immutable classes cannot be found. Proceed as if custom options |
| 271 // don't exist. |
| 272 "}\n", |
| 273 "immutable_file_class_name", |
| 274 name_resolver_->GetImmutableClassName(descriptor_->file()), |
| 275 "index", SimpleItoa(descriptor_->index())); |
| 276 } |
| 277 printer->Print( |
| 278 "return $immutable_package$.$descriptor_class$.$descriptor$\n" |
| 279 " .getEnumTypes().get($index$);\n", |
| 280 "immutable_package", FileJavaPackage(descriptor_->file(), true), |
| 281 "descriptor_class", |
| 282 name_resolver_->GetDescriptorClassName(descriptor_->file()), |
| 283 "descriptor", "getDescriptor()", |
| 284 "index", SimpleItoa(descriptor_->index())); |
| 285 printer->Outdent(); |
| 286 } |
| 243 } else { | 287 } else { |
| 244 printer->Print( | 288 printer->Print( |
| 245 " return $parent$.$descriptor$.getEnumTypes().get($index$);\n", | 289 " return $parent$.$descriptor$.getEnumTypes().get($index$);\n", |
| 246 "parent", name_resolver_->GetClassName(descriptor_->containing_type(), | 290 "parent", name_resolver_->GetClassName(descriptor_->containing_type(), |
| 247 immutable_api_), | 291 immutable_api_), |
| 248 "descriptor", descriptor_->containing_type()->options() | 292 "descriptor", descriptor_->containing_type()->options() |
| 249 .no_standard_descriptor_accessor() | 293 .no_standard_descriptor_accessor() |
| 250 ? "getDefaultInstance().getDescriptorForType()" | 294 ? "getDefaultInstance().getDescriptorForType()" |
| 251 : "getDescriptor()", | 295 : "getDescriptor()", |
| 252 "index", SimpleItoa(descriptor_->index())); | 296 "index", SimpleItoa(descriptor_->index())); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 return false; | 386 return false; |
| 343 } | 387 } |
| 344 } | 388 } |
| 345 return true; | 389 return true; |
| 346 } | 390 } |
| 347 | 391 |
| 348 } // namespace java | 392 } // namespace java |
| 349 } // namespace compiler | 393 } // namespace compiler |
| 350 } // namespace protobuf | 394 } // namespace protobuf |
| 351 } // namespace google | 395 } // namespace google |
| OLD | NEW |