diff options
author | Brian Duff <bduff@google.com> | 2013-10-15 18:35:44 -0700 |
---|---|---|
committer | Max Cai <maxtroy@google.com> | 2013-10-25 16:06:21 +0100 |
commit | ccc48faf20dbf3b3cddcffe78d198876d543529b (patch) | |
tree | 82a2f42e9d464661152539821093b14fbc068189 /src/google/protobuf/compiler/javanano/javanano_message.cc | |
parent | 42be1e79ccd670be36220222936aa7cacc6856f6 (diff) | |
download | external_protobuf-ccc48faf20dbf3b3cddcffe78d198876d543529b.zip external_protobuf-ccc48faf20dbf3b3cddcffe78d198876d543529b.tar.gz external_protobuf-ccc48faf20dbf3b3cddcffe78d198876d543529b.tar.bz2 |
Implement hashCode() and equals() behind a generator option.
The option is only called 'generate_equals' because:
- equals() is the main thing; hashCode() is there only to
complement equals();
- it's shorter;
- toString() should not be included in this option because
it's more for debugging and it's more likely to stop
ProGuard from working well.
Also shortened the "has bit" expression; was
((bitField & mask) == mask), now ((bitField & mask) != 0).
Both the Java code and the bytecode are slightly shorter.
Change-Id: Ic309a08a60883bf454eb6612679aa99611620e76
Diffstat (limited to 'src/google/protobuf/compiler/javanano/javanano_message.cc')
-rw-r--r-- | src/google/protobuf/compiler/javanano/javanano_message.cc | 84 |
1 files changed, 81 insertions, 3 deletions
diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc index c55ca55..63f8955 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message.cc +++ b/src/google/protobuf/compiler/javanano/javanano_message.cc @@ -198,6 +198,11 @@ void MessageGenerator::Generate(io::Printer* printer) { GenerateClear(printer); + if (params_.generate_equals()) { + GenerateEquals(printer); + GenerateHashCode(printer); + } + // If we have an extension range, generate accessors for extensions. if (params_.store_unknown_fields() && descriptor_->extension_range_count() > 0) { @@ -326,11 +331,11 @@ void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) { if (params_.store_unknown_fields()) { printer->Print( "if (unknownFieldData == null) {\n" - " unknownFieldData = \n" + " unknownFieldData =\n" " new java.util.ArrayList<com.google.protobuf.nano.UnknownFieldData>();\n" "}\n" - "if (!com.google.protobuf.nano.WireFormatNano.storeUnknownField(unknownFieldData, \n" - " input, tag)) {\n" + "if (!com.google.protobuf.nano.WireFormatNano.storeUnknownField(\n" + " unknownFieldData, input, tag)) {\n" " return this;\n" "}\n"); } else { @@ -427,6 +432,79 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { "}\n"); } +void MessageGenerator::GenerateEquals(io::Printer* printer) { + // Don't override if there are no fields. We could generate an + // equals method that compares types, but often empty messages + // are used as namespaces. + if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { + return; + } + + printer->Print( + "\n" + "@Override\n" + "public boolean equals(Object o) {\n"); + printer->Indent(); + printer->Print( + "if (o == this) {\n" + " return true;\n" + "}\n" + "if (!(o instanceof $classname$)) {\n" + " return false;\n" + "}\n" + "$classname$ other = ($classname$) o;\n", + "classname", descriptor_->name()); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + field_generators_.get(field).GenerateEqualsCode(printer); + } + + if (params_.store_unknown_fields()) { + printer->Print( + "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n" + " return other.unknownFieldData == null || other.unknownFieldData.isEmpty();" + "} else {\n" + " return unknownFieldData.equals(other.unknownFieldData);\n" + "}\n"); + } else { + printer->Print( + "return true;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator::GenerateHashCode(io::Printer* printer) { + if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) { + return; + } + + printer->Print( + "\n" + "@Override\n" + "public int hashCode() {\n"); + printer->Indent(); + + printer->Print("int result = 17;\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + field_generators_.get(field).GenerateHashCodeCode(printer); + } + + if (params_.store_unknown_fields()) { + printer->Print( + "result = 31 * result + (unknownFieldData == null || unknownFieldData.isEmpty()\n" + " ? 0 : unknownFieldData.hashCode());\n"); + } + + printer->Print("return result;\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + // =================================================================== } // namespace javanano |