| diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc |
| index 4c087db..cd18e28 100644 |
| --- a/src/google/protobuf/compiler/java/java_message.cc |
| +++ b/src/google/protobuf/compiler/java/java_message.cc |
| @@ -303,14 +303,14 @@ void MessageGenerator::Generate(io::Printer* printer) { |
| printer->Print( |
| "public $static$ final class $classname$ extends\n" |
| " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" |
| - " $classname$> implements $classname$OrBuilder {\n", |
| + " $classname$> implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage {\n", |
| "static", is_own_file ? "" : "static", |
| "classname", descriptor_->name()); |
| } else { |
| printer->Print( |
| "public $static$ final class $classname$ extends\n" |
| " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" |
| - " $classname$> implements $classname$OrBuilder {\n", |
| + " $classname$> implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage {\n", |
| "static", is_own_file ? "" : "static", |
| "classname", descriptor_->name()); |
| } |
| @@ -319,24 +319,56 @@ void MessageGenerator::Generate(io::Printer* printer) { |
| printer->Print( |
| "public $static$ final class $classname$ extends\n" |
| " com.google.protobuf.GeneratedMessage\n" |
| - " implements $classname$OrBuilder {\n", |
| + " implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage {\n", |
| "static", is_own_file ? "" : "static", |
| "classname", descriptor_->name()); |
| } else { |
| printer->Print( |
| "public $static$ final class $classname$ extends\n" |
| " com.google.protobuf.GeneratedMessageLite\n" |
| - " implements $classname$OrBuilder {\n", |
| + " implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedOutputStream.ByteBufGeneratedMessage {\n", |
| "static", is_own_file ? "" : "static", |
| "classname", descriptor_->name()); |
| } |
| } |
| + |
| + // Integers for bit fields. |
| + int totalBits = 0; |
| + for (int i = 0; i < descriptor_->field_count(); i++) { |
| + totalBits += field_generators_.get(descriptor_->field(i)) |
| + .GetNumBitsForMessage(); |
| + } |
| + int totalInts = (totalBits + 31) / 32; |
| + |
| printer->Indent(); |
| printer->Print( |
| "// Use $classname$.newBuilder() to construct.\n" |
| - "private $classname$(Builder builder) {\n" |
| - " super(builder);\n" |
| + "private io.netty.util.Recycler.Handle handle;\n" |
| + "private $classname$(io.netty.util.Recycler.Handle handle) {\n" |
| + " this.handle = handle;\n" |
| "}\n" |
| + "\n" |
| + " private static final io.netty.util.Recycler<$classname$> RECYCLER = new io.netty.util.Recycler<$classname$>() {\n" |
| + " protected $classname$ newObject(Handle handle) {\n" |
| + " return new $classname$(handle);\n" |
| + " }\n" |
| + " };\n" |
| + " \n" |
| + " public void recycle() {\n" |
| + " this.initFields();\n" |
| + " this.memoizedIsInitialized = -1;\n", |
| + "classname", descriptor_->name()); |
| + |
| + for (int i = 0; i < totalInts; i++) { |
| + printer->Print(" this.$bit_field_name$ = 0;\n", |
| + "bit_field_name", GetBitFieldName(i)); |
| + } |
| + |
| + printer->Print( |
| + " this.memoizedSerializedSize = -1;\n" |
| + " if (handle != null) { RECYCLER.recycle(this, handle); }\n" |
| + " }\n" |
| + " \n" |
| // Used when constructing the default instance, which cannot be initialized |
| // immediately because it may cyclically refer to other default instances. |
| "private $classname$(boolean noInit) {}\n" |
| @@ -365,13 +397,6 @@ void MessageGenerator::Generate(io::Printer* printer) { |
| messageGenerator.Generate(printer); |
| } |
| |
| - // Integers for bit fields. |
| - int totalBits = 0; |
| - for (int i = 0; i < descriptor_->field_count(); i++) { |
| - totalBits += field_generators_.get(descriptor_->field(i)) |
| - .GetNumBitsForMessage(); |
| - } |
| - int totalInts = (totalBits + 31) / 32; |
| for (int i = 0; i < totalInts; i++) { |
| printer->Print("private int $bit_field_name$;\n", |
| "bit_field_name", GetBitFieldName(i)); |
| @@ -450,7 +475,12 @@ GenerateMessageSerializationMethods(io::Printer* printer) { |
| ExtensionRangeOrdering()); |
| |
| printer->Print( |
| - "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" |
| + "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" |
| + " throws java.io.IOException {\n" |
| + " throw new RuntimeException(\"Cannot use CodedOutputStream\");\n" |
| + "}\n\n" |
| + |
| + "public void writeTo(com.yahoo.pulsar.common.util.protobuf.ByteBufCodedOutputStream output)\n" |
| " throws java.io.IOException {\n"); |
| printer->Indent(); |
| // writeTo(CodedOutputStream output) might be invoked without |
| @@ -567,14 +597,16 @@ GenerateParseFromMethods(io::Printer* printer) { |
| "public static $classname$ parseFrom(\n" |
| " com.google.protobuf.ByteString data)\n" |
| " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
| - " return newBuilder().mergeFrom(data).buildParsed();\n" |
| + // " return newBuilder().mergeFrom(data).buildParsed();\n" |
| + " throw new RuntimeException(\"Disabled\");\n" |
| "}\n" |
| "public static $classname$ parseFrom(\n" |
| " com.google.protobuf.ByteString data,\n" |
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
| " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
| - " return newBuilder().mergeFrom(data, extensionRegistry)\n" |
| - " .buildParsed();\n" |
| + // " return newBuilder().mergeFrom(data, extensionRegistry)\n" |
| + // " .buildParsed();\n" |
| + " throw new RuntimeException(\"Disabled\");\n" |
| "}\n" |
| "public static $classname$ parseFrom(byte[] data)\n" |
| " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
| @@ -674,13 +706,13 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) { |
| printer->Print( |
| "public static final class Builder extends\n" |
| " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n" |
| - " $classname$, Builder> implements $classname$OrBuilder {\n", |
| + " $classname$, Builder> implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder {\n", |
| "classname", ClassName(descriptor_)); |
| } else { |
| printer->Print( |
| "public static final class Builder extends\n" |
| " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n" |
| - " $classname$, Builder> implements $classname$OrBuilder {\n", |
| + " $classname$, Builder> implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder {\n", |
| "classname", ClassName(descriptor_)); |
| } |
| } else { |
| @@ -688,14 +720,14 @@ void MessageGenerator::GenerateBuilder(io::Printer* printer) { |
| printer->Print( |
| "public static final class Builder extends\n" |
| " com.google.protobuf.GeneratedMessage.Builder<Builder>\n" |
| - " implements $classname$OrBuilder {\n", |
| + " implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder {\n", |
| "classname", ClassName(descriptor_)); |
| } else { |
| printer->Print( |
| "public static final class Builder extends\n" |
| " com.google.protobuf.GeneratedMessageLite.Builder<\n" |
| " $classname$, Builder>\n" |
| - " implements $classname$OrBuilder {\n", |
| + " implements $classname$OrBuilder, com.yahoo.pulsar.common.util.protobuf.ByteBufCodedInputStream.ByteBufMessageBuilder {\n", |
| "classname", ClassName(descriptor_)); |
| } |
| } |
| @@ -760,9 +792,21 @@ void MessageGenerator::GenerateDescriptorMethods(io::Printer* printer) { |
| void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { |
| printer->Print( |
| "// Construct using $classname$.newBuilder()\n" |
| - "private Builder() {\n" |
| + "private final io.netty.util.Recycler.Handle handle;\n" |
| + "private Builder(io.netty.util.Recycler.Handle handle) {\n" |
| + " this.handle = handle;\n" |
| " maybeForceBuilderInitialization();\n" |
| "}\n" |
| + "private final static io.netty.util.Recycler<Builder> RECYCLER = new io.netty.util.Recycler<Builder>() {\n" |
| + " protected Builder newObject(io.netty.util.Recycler.Handle handle) {\n" |
| + " return new Builder(handle);\n" |
| + " }\n" |
| + " };\n" |
| + "\n" |
| + " public void recycle() {\n" |
| + " clear();\n" |
| + " if (handle != null) {RECYCLER.recycle(this, handle);}\n" |
| + " }\n" |
| "\n", |
| "classname", ClassName(descriptor_)); |
| |
| @@ -801,7 +845,8 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { |
| |
| printer->Print( |
| "private static Builder create() {\n" |
| - " return new Builder();\n" |
| + " return RECYCLER.get();\n" |
| + // " return new Builder(null);\n" |
| "}\n" |
| "\n" |
| "public Builder clear() {\n" |
| @@ -864,7 +909,8 @@ void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) { |
| "}\n" |
| "\n" |
| "public $classname$ buildPartial() {\n" |
| - " $classname$ result = new $classname$(this);\n", |
| + " $classname$ result = $classname$.RECYCLER.get();\n", |
| + // " $classname$ result = new $classname$(null);\n", |
| "classname", ClassName(descriptor_)); |
| |
| printer->Indent(); |
| @@ -973,8 +1019,13 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { |
| SortFieldsByNumber(descriptor_)); |
| |
| printer->Print( |
| + "public Builder mergeFrom(com.google.protobuf.CodedInputStream input,\n" |
| + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
| + " throws java.io.IOException {\n" |
| + " throw new java.io.IOException(\"Merge from CodedInputStream is disabled\");\n" |
| + " }\n" |
| "public Builder mergeFrom(\n" |
| - " com.google.protobuf.CodedInputStream input,\n" |
| + " com.yahoo.pulsar.common.util.protobuf.ByteBufCodedInputStream input,\n" |
| " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
| " throws java.io.IOException {\n"); |
| printer->Indent(); |
| @@ -1017,7 +1068,7 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) { |
| " $on_changed$\n" |
| " return this;\n" |
| "default: {\n" |
| - " if (!parseUnknownField(input, extensionRegistry, tag)) {\n" |
| + " if (!input.skipField(tag)) {\n" |
| " $on_changed$\n" |
| " return this;\n" // it's an endgroup tag |
| " }\n" |
| diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc |
| index 251945a..1212be9 100644 |
| --- a/src/google/protobuf/compiler/java/java_message_field.cc |
| +++ b/src/google/protobuf/compiler/java/java_message_field.cc |
| @@ -371,7 +371,8 @@ GenerateParsingCode(io::Printer* printer) const { |
| } |
| |
| printer->Print(variables_, |
| - "set$capitalized_name$(subBuilder.buildPartial());\n"); |
| + "set$capitalized_name$(subBuilder.buildPartial());\n" |
| + "subBuilder.recycle();\n"); |
| } |
| |
| void MessageFieldGenerator:: |
| diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc |
| index 91e6878..cfee383 100644 |
| --- a/src/google/protobuf/message.cc |
| +++ b/src/google/protobuf/message.cc |
| @@ -32,6 +32,7 @@ |
| // Based on original Protocol Buffers design by |
| // Sanjay Ghemawat, Jeff Dean, and others. |
| |
| +#include <iostream> |
| #include <stack> |
| #include <google/protobuf/stubs/hash.h> |
| |