diff options
author | Jon Skeet <jonskeet@google.com> | 2015-06-26 17:37:14 +0100 |
---|---|---|
committer | Jon Skeet <jonskeet@google.com> | 2015-06-30 13:20:30 +0100 |
commit | f2a27cc2c71b4dae3ff230574a73c1de88dd61b7 (patch) | |
tree | 58cdbbbd9262732c9a104171f2563f0f2da85acb /src | |
parent | 241e17ba78b71a7ecccb289914ecaeab203b2373 (diff) | |
download | protobuf-f2a27cc2c71b4dae3ff230574a73c1de88dd61b7.tar.gz protobuf-f2a27cc2c71b4dae3ff230574a73c1de88dd61b7.tar.bz2 protobuf-f2a27cc2c71b4dae3ff230574a73c1de88dd61b7.zip |
First pass (not yet compiling) at removing all the array handling code from Coded*Stream.
Prod code works, but some tests are broken. Obviously those need fixing, then more tests,
and review benchmarks.
Diffstat (limited to 'src')
3 files changed, 27 insertions, 102 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc index d223273c..4445c281 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -49,7 +49,6 @@ namespace csharp { RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( const FieldDescriptor* descriptor, int fieldOrdinal) : FieldGeneratorBase(descriptor, fieldOrdinal) { - variables_["packed"] = descriptor->is_packed() ? "Packed" : ""; } RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() { @@ -57,6 +56,10 @@ RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() { } void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) { + printer->Print( + variables_, + "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" + " = pb::FieldCodec.ForEnum($tag$, x => (int) x, x => ($type_name$) x);"); printer->Print(variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); AddDeprecatedFlag(printer); @@ -76,53 +79,19 @@ void RepeatedEnumFieldGenerator::GenerateMergingCode(io::Printer* printer) { void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, - "input.ReadEnumArray<$type_name$>($name$_);\n"); + "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) { printer->Print( variables_, - "if ($name$_.Count > 0) {\n"); - printer->Indent(); - if (descriptor_->is_packed()) { - printer->Print( - variables_, - "output.WriteRawTag($tag_bytes$);\n" - "output.WritePackedEnumArray($name$_);\n"); - } else { - printer->Print( - variables_, - "output.Write$capitalized_type_name$Array($number$, $name$_);\n"); - } - printer->Outdent(); - printer->Print("}\n"); + "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } -void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { - // TODO(jonskeet): Move all this code into CodedOutputStream? It's a lot to repeat everywhere... - printer->Print( - variables_, - "if ($name$_.Count > 0) {\n"); - printer->Indent(); - printer->Print("int dataSize = 0;\n"); +void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( variables_, - "foreach ($type_name$ element in $name$_) {\n" - " dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element);\n" - "}\n" - "size += dataSize;\n"); - int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); - if (descriptor_->is_packed()) { - printer->Print( - "size += $tag_size$ + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);\n", - "tag_size", SimpleItoa(tagSize)); - } else { - printer->Print( - "size += $tag_size$ * $name$_.Count;\n", - "tag_size", SimpleItoa(tagSize), "name", name()); - } - printer->Outdent(); - printer->Print("}\n"); + "size += $name$_.CalculateSize(_repeated_$name$_codec);\n"); } void RepeatedEnumFieldGenerator::WriteHash(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc index 400f0e4f..c74e5d0d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -57,6 +57,10 @@ RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() { void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) { printer->Print( variables_, + "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" + " = pb::FieldCodec.ForMessage($tag$, $type_name$.Parser);\n"); + printer->Print( + variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); AddDeprecatedFlag(printer); printer->Print( @@ -75,28 +79,19 @@ void RepeatedMessageFieldGenerator::GenerateMergingCode(io::Printer* printer) { void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) { printer->Print( variables_, - "input.ReadMessageArray($name$_, $type_name$.Parser);\n"); + "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) { - // TODO(jonskeet): Bake the foreach loop into the generated code? We lose the - // advantage of knowing the tag bytes this way :( printer->Print( variables_, - "if ($name$_.Count > 0) {\n" - " output.WriteMessageArray($number$, $name$_);\n" - "}\n"); + "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( variables_, - "if ($name$_.Count > 0) {\n" - " foreach ($type_name$ element in $name$_) {\n" - " size += pb::CodedOutputStream.ComputeMessageSize(element);\n" - " }\n" - " size += $tag_size$ * $name$_.Count;\n" - "}\n"); + "size += $name$_.CalculateSize(_repeated_$name$_codec);\n"); } void RepeatedMessageFieldGenerator::WriteHash(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc index a78a74c0..a3014da8 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -49,7 +49,6 @@ namespace csharp { RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( const FieldDescriptor* descriptor, int fieldOrdinal) : FieldGeneratorBase(descriptor, fieldOrdinal) { - variables_["packed"] = descriptor->is_packed() ? "Packed" : ""; } RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() { @@ -57,6 +56,10 @@ RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() { } void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) { + printer->Print( + variables_, + "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" + " = pb::FieldCodec.For$capitalized_type_name$($tag$);\n"); printer->Print(variables_, "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); AddDeprecatedFlag(printer); @@ -74,63 +77,21 @@ void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) } void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) { - printer->Print(variables_, - "input.Read$capitalized_type_name$Array($name$_);\n"); + printer->Print( + variables_, + "$name$_.AddEntriesFrom(input, _repeated_$name$_codec);\n"); } -void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode( - io::Printer* printer) { +void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) { printer->Print( variables_, - "if ($name$_.Count > 0) {\n"); - printer->Indent(); - if (descriptor_->is_packed()) { - printer->Print( - variables_, - "output.WriteRawTag($tag_bytes$);\n" - "output.WritePacked$capitalized_type_name$Array($name$_);\n"); - } else { - printer->Print( - variables_, - "output.Write$capitalized_type_name$Array($number$, $name$_);\n"); - } - printer->Outdent(); - printer->Print("}\n"); + "$name$_.WriteTo(output, _repeated_$name$_codec);\n"); } -void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode( - io::Printer* printer) { - // TODO(jonskeet): Do this in the runtime if possible. It's a pain, but it must be feasible... +void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { printer->Print( - "if ($name$_.Count > 0) {\n", - "name", name()); - printer->Indent(); - printer->Print("int dataSize = 0;\n"); - int fixedSize = GetFixedSize(descriptor_->type()); - if (fixedSize == -1) { - printer->Print( - variables_, - "foreach ($type_name$ element in $name$_) {\n" - " dataSize += pb::CodedOutputStream.Compute$capitalized_type_name$Size(element);\n" - "}\n"); - } else { - printer->Print( - "dataSize = $size$ * $name$_.Count;\n", - "size", SimpleItoa(fixedSize), "name", name()); - } - printer->Print("size += dataSize;\n"); - int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); - if (descriptor_->is_packed()) { - printer->Print( - "size += $tag_size$ + pb::CodedOutputStream.ComputeInt32Size(dataSize);\n", - "tag_size", SimpleItoa(tagSize)); - } else { - printer->Print( - "size += $tag_size$ * $name$_.Count;\n", - "tag_size", SimpleItoa(tagSize), "name", name()); - } - printer->Outdent(); - printer->Print("}\n"); + variables_, + "size += $name$_.CalculateSize(_repeated_$name$_codec);\n"); } void RepeatedPrimitiveFieldGenerator::WriteHash(io::Printer* printer) { |