aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/java/java_message.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/compiler/java/java_message.cc')
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc132
1 files changed, 115 insertions, 17 deletions
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 09b0fd94..80d6e9ad 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -255,6 +255,18 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
field_generators_.get(descriptor_->field(i))
.GenerateInterfaceMembers(printer);
}
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "\n"
+ "public $classname$.$oneof_capitalized_name$Case "
+ "get$oneof_capitalized_name$Case();\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name,
+ "classname",
+ context_->GetNameResolver()->GetImmutableClassName(
+ descriptor_));
+ }
printer->Outdent();
printer->Print("}\n");
@@ -292,8 +304,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
" com.google.protobuf.GeneratedMessage implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n");
-
- builder_type = "com.google.protobuf.GeneratedMessage.Builder";
+ builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
}
printer->Indent();
// Using builder_type, instead of Builder, prevents the Builder class from
@@ -435,6 +446,10 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
"\n");
}
+ if (IsAnyMessage(descriptor_)) {
+ GenerateAnyMethods(printer);
+ }
+
// Fields
for (int i = 0; i < descriptor_->field_count(); i++) {
printer->Print("public static final int $constant_name$ = $number$;\n",
@@ -578,9 +593,8 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Print(
"}\n"
"\n"
- "private int memoizedSerializedSize = -1;\n"
"public int getSerializedSize() {\n"
- " int size = memoizedSerializedSize;\n"
+ " int size = memoizedSize;\n"
" if (size != -1) return size;\n"
"\n"
" size = 0;\n");
@@ -612,7 +626,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Outdent();
printer->Print(
- " memoizedSerializedSize = size;\n"
+ " memoizedSize = size;\n"
" return size;\n"
"}\n"
"\n");
@@ -948,22 +962,58 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
printer->Print("boolean result = true;\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
- const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
- bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
- if (check_has_bits) {
+ if (field->containing_oneof() == NULL) {
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+ if (check_has_bits) {
+ printer->Print(
+ "result = result && (has$name$() == other.has$name$());\n"
+ "if (has$name$()) {\n",
+ "name", info->capitalized_name);
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ if (check_has_bits) {
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ }
+ }
+
+ // Compare oneofs.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "result = result && get$oneof_capitalized_name$Case().equals(\n"
+ " other.get$oneof_capitalized_name$Case());\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name);
+ printer->Print(
+ "if (!result) return false;\n"
+ "switch ($oneof_name$Case_) {\n",
+ "oneof_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name);
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
printer->Print(
- "result = result && (has$name$() == other.has$name$());\n"
- "if (has$name$()) {\n",
- "name", info->capitalized_name);
+ "case $field_number$:\n",
+ "field_number",
+ SimpleItoa(field->number()));
printer->Indent();
- }
- field_generators_.get(field).GenerateEqualsCode(printer);
- if (check_has_bits) {
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ printer->Print("break;\n");
printer->Outdent();
- printer->Print(
- "}\n");
}
+ printer->Print(
+ "case 0:\n"
+ "default:\n");
+ printer->Outdent();
+ printer->Print("}\n");
}
+
if (PreserveUnknownFields(descriptor_)) {
// Always consider unknown fields for equality. This will sometimes return
// false for non-canonical ordering when running in LITE_RUNTIME but it's
@@ -1198,7 +1248,7 @@ GenerateParsingConstructor(io::Printer* printer) {
// ===================================================================
void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
printer->Print(
- "public static final com.google.protobuf.Parser<$classname$> PARSER =\n"
+ "private static final com.google.protobuf.Parser<$classname$> PARSER =\n"
" new com.google.protobuf.AbstractParser<$classname$>() {\n",
"classname", descriptor_->name());
printer->Indent();
@@ -1250,6 +1300,10 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
"\n");
printer->Print(
+ "public static com.google.protobuf.Parser<$classname$> parser() {\n"
+ " return PARSER;\n"
+ "}\n"
+ "\n"
"@java.lang.Override\n"
"public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
" return PARSER;\n"
@@ -1269,6 +1323,50 @@ void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
}
+void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
+ printer->Print(
+ "private static String getTypeUrl(\n"
+ " com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
+ " return \"type.googleapis.com/\" + descriptor.getFullName();\n"
+ "}\n"
+ "\n"
+ "public static <T extends com.google.protobuf.Message> Any pack(\n"
+ " T message) {\n"
+ " return Any.newBuilder()\n"
+ " .setTypeUrl(getTypeUrl(message.getDescriptorForType()))\n"
+ " .setValue(message.toByteString())\n"
+ " .build();\n"
+ "}\n"
+ "\n"
+ "public <T extends com.google.protobuf.Message> boolean is(\n"
+ " java.lang.Class<T> clazz) {\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " return getTypeUrl().equals(\n"
+ " getTypeUrl(defaultInstance.getDescriptorForType()));\n"
+ "}\n"
+ "\n"
+ "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
+ "\n"
+ "public <T extends com.google.protobuf.Message> T unpack(\n"
+ " java.lang.Class<T> clazz)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " if (!is(clazz)) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " \"Type of the Any messsage does not match the given class.\");\n"
+ " }\n"
+ " if (cachedUnpackValue != null) {\n"
+ " return (T) cachedUnpackValue;\n"
+ " }\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " T result = (T) defaultInstance.getParserForType()\n"
+ " .parseFrom(getValue());\n"
+ " cachedUnpackValue = result;\n"
+ " return result;\n"
+ "}\n");
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf