Pārlūkot izejas kodu

Use the fact that we know the tag size and bytes at codegen time to optimize.

Jon Skeet 10 gadi atpakaļ
vecāks
revīzija
828b7e61d0

+ 19 - 12
csharp/src/AddressBook/Addressbook.cs

@@ -139,13 +139,16 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
 
     public void WriteTo(pb::CodedOutputStream output) {
       if (Name.Length != 0) {
-        output.WriteString(1, Name);
+        output.WriteRawTag(10);
+        output.WriteString(Name);
       }
       if (Id != 0) {
-        output.WriteInt32(2, Id);
+        output.WriteRawTag(16);
+        output.WriteInt32(Id);
       }
       if (Email.Length != 0) {
-        output.WriteString(3, Email);
+        output.WriteRawTag(26);
+        output.WriteString(Email);
       }
       if (phone_.Count > 0) {
         output.WriteMessageArray(4, phone_);
@@ -155,18 +158,19 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     public int CalculateSize() {
       int size = 0;
       if (Name.Length != 0) {
-        size += pb::CodedOutputStream.ComputeStringSize(1, Name);
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
       }
       if (Id != 0) {
-        size += pb::CodedOutputStream.ComputeInt32Size(2, Id);
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Id);
       }
       if (Email.Length != 0) {
-        size += pb::CodedOutputStream.ComputeStringSize(3, Email);
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Email);
       }
       if (phone_.Count > 0) {
         foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber element in phone_) {
-          size += pb::CodedOutputStream.ComputeMessageSize(4, element);
+          size += pb::CodedOutputStream.ComputeMessageSize(element);
         }
+        size += 1 * phone_.Count;
       }
       return size;
     }
@@ -286,20 +290,22 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
 
         public void WriteTo(pb::CodedOutputStream output) {
           if (Number.Length != 0) {
-            output.WriteString(1, Number);
+            output.WriteRawTag(10);
+            output.WriteString(Number);
           }
           if (Type != global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType.HOME) {
-            output.WriteEnum(2, (int) Type);
+            output.WriteRawTag(16);
+            output.WriteEnum((int) Type);
           }
         }
 
         public int CalculateSize() {
           int size = 0;
           if (Number.Length != 0) {
-            size += pb::CodedOutputStream.ComputeStringSize(1, Number);
+            size += 1 + pb::CodedOutputStream.ComputeStringSize(Number);
           }
           if (Type != global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType.HOME) {
-            size += pb::CodedOutputStream.ComputeEnumSize(2, (int) Type);
+            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
           }
           return size;
         }
@@ -401,8 +407,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       int size = 0;
       if (person_.Count > 0) {
         foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person element in person_) {
-          size += pb::CodedOutputStream.ComputeMessageSize(1, element);
+          size += pb::CodedOutputStream.ComputeMessageSize(element);
         }
+        size += 1 * person_.Count;
       }
       return size;
     }

+ 2 - 0
csharp/src/ProtoMunge/Program.cs

@@ -38,6 +38,8 @@ using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.IO;
+using Google.Protobuf;
+using Google.Protobuf.Descriptors;
 using Google.ProtocolBuffers.Descriptors;
 
 namespace Google.ProtocolBuffers.ProtoMunge

+ 6 - 3
csharp/src/ProtocolBuffers.Test/CodedInputStreamTest.cs

@@ -479,7 +479,8 @@ namespace Google.Protobuf
             int msgSize = 1 + 1 + arraySize;
             byte[] bytes = new byte[msgSize];
             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
-            output.WritePackedInt32Array(8, new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
+            output.WriteTag(8, WireFormat.WireType.LengthDelimited);
+            output.WritePackedInt32Array(new RepeatedField<int> { 0, -1, -2, -3, -4, -5 });
 
             Assert.AreEqual(0, output.SpaceLeft);
 
@@ -527,8 +528,10 @@ namespace Google.Protobuf
             using (var ms = new MemoryStream())
             {
                 CodedOutputStream output = CodedOutputStream.CreateInstance(ms);
-                output.WriteBytes(1, ByteString.CopyFrom(new byte[100]));
-                output.WriteBytes(2, ByteString.CopyFrom(new byte[100]));
+                output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+                output.WriteBytes(ByteString.CopyFrom(new byte[100]));
+                output.WriteTag(2, WireFormat.WireType.LengthDelimited);
+                output.WriteBytes(ByteString.CopyFrom(new byte[100]));
                 output.Flush();
 
                 ms.Position = 0;

+ 11 - 25
csharp/src/ProtocolBuffers.Test/CodedOutputStreamTest.cs

@@ -295,12 +295,12 @@ namespace Google.Protobuf
         [Test]
         public void TestNegativeEnumNoTag()
         {
-            Assert.AreEqual(10, CodedOutputStream.ComputeInt32SizeNoTag(-2));
-            Assert.AreEqual(10, CodedOutputStream.ComputeEnumSizeNoTag((int) TestNegEnum.Value));
+            Assert.AreEqual(10, CodedOutputStream.ComputeInt32Size(-2));
+            Assert.AreEqual(10, CodedOutputStream.ComputeEnumSize((int) TestNegEnum.Value));
 
             byte[] bytes = new byte[10];
             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
-            output.WriteEnumNoTag((int) TestNegEnum.Value);
+            output.WriteEnum((int) TestNegEnum.Value);
 
             Assert.AreEqual(0, output.SpaceLeft);
             Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
@@ -308,21 +308,6 @@ namespace Google.Protobuf
 
         enum TestNegEnum { None = 0, Value = -2 }
 
-        [Test]
-        public void TestNegativeEnumWithTag()
-        {
-            Assert.AreEqual(11, CodedOutputStream.ComputeInt32Size(8, -2));
-            Assert.AreEqual(11, CodedOutputStream.ComputeEnumSize(8, (int) TestNegEnum.Value));
-
-            byte[] bytes = new byte[11];
-            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
-            output.WriteEnum(8, (int) TestNegEnum.Value);
-
-            Assert.AreEqual(0, output.SpaceLeft);
-            //fyi, 0x40 == 0x08 << 3 + 0, field num + wire format shift
-            Assert.AreEqual("40-FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
-        }
-
         [Test]
         public void TestNegativeEnumArrayPacked()
         {
@@ -330,7 +315,8 @@ namespace Google.Protobuf
             int msgSize = 1 + 1 + arraySize;
             byte[] bytes = new byte[msgSize];
             CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
-            output.WritePackedEnumArray(8, new RepeatedField<TestNegEnum> {
+            output.WriteTag(8, WireFormat.WireType.LengthDelimited);
+            output.WritePackedEnumArray(new RepeatedField<TestNegEnum> {
                 0, (TestNegEnum) (-1), TestNegEnum.Value, (TestNegEnum) (-3), (TestNegEnum) (-4), (TestNegEnum) (-5) });
 
             Assert.AreEqual(0, output.SpaceLeft);
@@ -384,17 +370,17 @@ namespace Google.Protobuf
                 // Field 11: numeric value: 500
                 cout.WriteTag(11, WireFormat.WireType.Varint);
                 Assert.AreEqual(1, cout.Position);
-                cout.WriteInt32NoTag(500);
+                cout.WriteInt32(500);
                 Assert.AreEqual(3, cout.Position);
                 //Field 12: length delimited 120 bytes
                 cout.WriteTag(12, WireFormat.WireType.LengthDelimited);
                 Assert.AreEqual(4, cout.Position);
-                cout.WriteBytesNoTag(ByteString.CopyFrom(content));
+                cout.WriteBytes(ByteString.CopyFrom(content));
                 Assert.AreEqual(115, cout.Position);
                 // Field 13: fixed numeric value: 501
                 cout.WriteTag(13, WireFormat.WireType.Fixed32);
                 Assert.AreEqual(116, cout.Position);
-                cout.WriteSFixed32NoTag(501);
+                cout.WriteSFixed32(501);
                 Assert.AreEqual(120, cout.Position);
                 cout.Flush();
             }
@@ -405,17 +391,17 @@ namespace Google.Protobuf
                 // Field 1: numeric value: 500
                 cout.WriteTag(1, WireFormat.WireType.Varint);
                 Assert.AreEqual(1, cout.Position);
-                cout.WriteInt32NoTag(500);
+                cout.WriteInt32(500);
                 Assert.AreEqual(3, cout.Position);
                 //Field 2: length delimited 120 bytes
                 cout.WriteTag(2, WireFormat.WireType.LengthDelimited);
                 Assert.AreEqual(4, cout.Position);
-                cout.WriteBytesNoTag(ByteString.CopyFrom(child));
+                cout.WriteBytes(ByteString.CopyFrom(child));
                 Assert.AreEqual(125, cout.Position);
                 // Field 3: fixed numeric value: 500
                 cout.WriteTag(3, WireFormat.WireType.Fixed32);
                 Assert.AreEqual(126, cout.Position);
-                cout.WriteSFixed32NoTag(501);
+                cout.WriteSFixed32(501);
                 Assert.AreEqual(130, cout.Position);
                 cout.Flush();
             }

+ 3 - 2
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportProto3.cs

@@ -109,14 +109,15 @@ namespace Google.Protobuf.TestProtos {
 
     public void WriteTo(pb::CodedOutputStream output) {
       if (D != 0) {
-        output.WriteInt32(1, D);
+        output.WriteRawTag(8);
+        output.WriteInt32(D);
       }
     }
 
     public int CalculateSize() {
       int size = 0;
       if (D != 0) {
-        size += pb::CodedOutputStream.ComputeInt32Size(1, D);
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(D);
       }
       return size;
     }

+ 3 - 2
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestImportPublicProto3.cs

@@ -94,14 +94,15 @@ namespace Google.Protobuf.TestProtos {
 
     public void WriteTo(pb::CodedOutputStream output) {
       if (E != 0) {
-        output.WriteInt32(1, E);
+        output.WriteRawTag(8);
+        output.WriteInt32(E);
       }
     }
 
     public int CalculateSize() {
       int size = 0;
       if (E != 0) {
-        size += pb::CodedOutputStream.ComputeInt32Size(1, E);
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(E);
       }
       return size;
     }

+ 31 - 24
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestIssues.cs

@@ -155,25 +155,27 @@ namespace UnitTest.Issues.TestProtos {
 
     public void WriteTo(pb::CodedOutputStream output) {
       if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
-        output.WriteEnum(1, (int) Value);
+        output.WriteRawTag(8);
+        output.WriteEnum((int) Value);
       }
       if (values_.Count > 0) {
         output.WriteEnumArray(2, values_);
       }
       if (packedValues_.Count > 0) {
-        output.WritePackedEnumArray(3, packedValues_);
+        output.WriteRawTag(26);
+        output.WritePackedEnumArray(packedValues_);
       }
     }
 
     public int CalculateSize() {
       int size = 0;
       if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
-        size += pb::CodedOutputStream.ComputeEnumSize(1, (int) Value);
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Value);
       }
       if (values_.Count > 0) {
         int dataSize = 0;
         foreach (global::UnitTest.Issues.TestProtos.NegativeEnum element in values_) {
-          dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
+          dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element);
         }
         size += dataSize;
         size += 1 * values_.Count;
@@ -181,11 +183,10 @@ namespace UnitTest.Issues.TestProtos {
       if (packedValues_.Count > 0) {
         int dataSize = 0;
         foreach (global::UnitTest.Issues.TestProtos.NegativeEnum element in packedValues_) {
-          dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
+          dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element);
         }
         size += dataSize;
-        size += 1;
-        size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);
+        size += 1 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);
       }
       return size;
     }
@@ -305,7 +306,7 @@ namespace UnitTest.Issues.TestProtos {
     public static pb::MessageParser<DeprecatedFieldsMessage> Parser { get { return _parser; } }
 
     private static readonly string[] _fieldNames = new string[] { "EnumArray", "EnumValue", "MessageArray", "MessageValue", "PrimitiveArray", "PrimitiveValue" };
-    private static readonly uint[] _fieldTags = new uint[] { 48, 40, 34, 26, 16, 8 };
+    private static readonly uint[] _fieldTags = new uint[] { 50, 40, 34, 26, 18, 8 };
     public static pbd::MessageDescriptor Descriptor {
       get { return global::UnitTest.Issues.TestProtos.UnittestIssues.internal__static_unittest_issues_DeprecatedFieldsMessage__Descriptor; }
     }
@@ -397,57 +398,62 @@ namespace UnitTest.Issues.TestProtos {
 
     public void WriteTo(pb::CodedOutputStream output) {
       if (PrimitiveValue != 0) {
-        output.WriteInt32(1, PrimitiveValue);
+        output.WriteRawTag(8);
+        output.WriteInt32(PrimitiveValue);
       }
       if (primitiveArray_.Count > 0) {
-        output.WritePackedInt32Array(2, primitiveArray_);
+        output.WriteRawTag(18);
+        output.WritePackedInt32Array(primitiveArray_);
       }
       if (messageValue_ != null) {
-        output.WriteMessage(3, MessageValue);
+        output.WriteRawTag(26);
+        output.WriteMessage(MessageValue);
       }
       if (messageArray_.Count > 0) {
         output.WriteMessageArray(4, messageArray_);
       }
       if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
-        output.WriteEnum(5, (int) EnumValue);
+        output.WriteRawTag(40);
+        output.WriteEnum((int) EnumValue);
       }
       if (enumArray_.Count > 0) {
-        output.WritePackedEnumArray(6, enumArray_);
+        output.WriteRawTag(50);
+        output.WritePackedEnumArray(enumArray_);
       }
     }
 
     public int CalculateSize() {
       int size = 0;
       if (PrimitiveValue != 0) {
-        size += pb::CodedOutputStream.ComputeInt32Size(1, PrimitiveValue);
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(PrimitiveValue);
       }
       if (primitiveArray_.Count > 0) {
         int dataSize = 0;
         foreach (int element in primitiveArray_) {
-          dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
+          dataSize += pb::CodedOutputStream.ComputeInt32Size(element);
         }
         size += dataSize;
-        size += 1 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(dataSize);
       }
       if (messageValue_ != null) {
-        size += pb::CodedOutputStream.ComputeMessageSize(3, MessageValue);
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageValue);
       }
       if (messageArray_.Count > 0) {
         foreach (global::UnitTest.Issues.TestProtos.DeprecatedChild element in messageArray_) {
-          size += pb::CodedOutputStream.ComputeMessageSize(4, element);
+          size += pb::CodedOutputStream.ComputeMessageSize(element);
         }
+        size += 1 * messageArray_.Count;
       }
       if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
-        size += pb::CodedOutputStream.ComputeEnumSize(5, (int) EnumValue);
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumValue);
       }
       if (enumArray_.Count > 0) {
         int dataSize = 0;
         foreach (global::UnitTest.Issues.TestProtos.DeprecatedEnum element in enumArray_) {
-          dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
+          dataSize += pb::CodedOutputStream.ComputeEnumSize((int) element);
         }
         size += dataSize;
-        size += 1;
-        size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);
+        size += 1 + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);
       }
       return size;
     }
@@ -568,14 +574,15 @@ namespace UnitTest.Issues.TestProtos {
 
     public void WriteTo(pb::CodedOutputStream output) {
       if (Item != 0) {
-        output.WriteInt32(1, Item);
+        output.WriteRawTag(8);
+        output.WriteInt32(Item);
       }
     }
 
     public int CalculateSize() {
       int size = 0;
       if (Item != 0) {
-        size += pb::CodedOutputStream.ComputeInt32Size(1, Item);
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Item);
       }
       return size;
     }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 245 - 173
csharp/src/ProtocolBuffers.Test/TestProtos/UnittestProto3.cs


+ 20 - 200
csharp/src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs

@@ -47,193 +47,13 @@ namespace Google.Protobuf
     public sealed partial class CodedOutputStream
     {
         private const int LittleEndian64Size = 8;
-        private const int LittleEndian32Size = 4;
+        private const int LittleEndian32Size = 4;        
 
         /// <summary>
         /// Compute the number of bytes that would be needed to encode a
         /// double field, including the tag.
         /// </summary>
-        public static int ComputeDoubleSize(int fieldNumber, double value)
-        {
-            return ComputeTagSize(fieldNumber) + LittleEndian64Size;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// float field, including the tag.
-        /// </summary>
-        public static int ComputeFloatSize(int fieldNumber, float value)
-        {
-            return ComputeTagSize(fieldNumber) + LittleEndian32Size;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// uint64 field, including the tag.
-        /// </summary>
-        public static int ComputeUInt64Size(int fieldNumber, ulong value)
-        {
-            return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(value);
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode an
-        /// int64 field, including the tag.
-        /// </summary>
-        public static int ComputeInt64Size(int fieldNumber, long value)
-        {
-            return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size((ulong) value);
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode an
-        /// int32 field, including the tag.
-        /// </summary>
-        public static int ComputeInt32Size(int fieldNumber, int value)
-        {
-            return ComputeTagSize(fieldNumber) + ComputeInt32SizeNoTag(value);
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// fixed64 field, including the tag.
-        /// </summary>
-        public static int ComputeFixed64Size(int fieldNumber, ulong value)
-        {
-            return ComputeTagSize(fieldNumber) + LittleEndian64Size;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// fixed32 field, including the tag.
-        /// </summary>
-        public static int ComputeFixed32Size(int fieldNumber, uint value)
-        {
-            return ComputeTagSize(fieldNumber) + LittleEndian32Size;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// bool field, including the tag.
-        /// </summary>
-        public static int ComputeBoolSize(int fieldNumber, bool value)
-        {
-            return ComputeTagSize(fieldNumber) + 1;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// string field, including the tag.
-        /// </summary>
-        public static int ComputeStringSize(int fieldNumber, String value)
-        {
-            int byteArraySize = UTF8.GetByteCount(value);
-            return ComputeTagSize(fieldNumber) +
-                   ComputeRawVarint32Size((uint) byteArraySize) +
-                   byteArraySize;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// group field, including the tag.
-        /// </summary>
-        public static int ComputeGroupSize(int fieldNumber, IMessage value)
-        {
-            return ComputeTagSize(fieldNumber)*2 + value.CalculateSize();
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// group field represented by an UnknownFieldSet, including the tag.
-        /// </summary>
-        [Obsolete]
-        public static int ComputeUnknownGroupSize(int fieldNumber,
-                                                  IMessage value)
-        {
-            return ComputeTagSize(fieldNumber)*2 + value.CalculateSize();
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode an
-        /// embedded message field, including the tag.
-        /// </summary>
-        public static int ComputeMessageSize(int fieldNumber, IMessage value)
-        {
-            int size = value.CalculateSize();
-            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint) size) + size;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// bytes field, including the tag.
-        /// </summary>
-        public static int ComputeBytesSize(int fieldNumber, ByteString value)
-        {
-            return ComputeTagSize(fieldNumber) +
-                   ComputeRawVarint32Size((uint) value.Length) +
-                   value.Length;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// uint32 field, including the tag.
-        /// </summary>
-        public static int ComputeUInt32Size(int fieldNumber, uint value)
-        {
-            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(value);
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// enum field, including the tag. The caller is responsible for
-        /// converting the enum value to its numeric value.
-        /// </summary>
-        public static int ComputeEnumSize(int fieldNumber, int value)
-        {
-            return ComputeTagSize(fieldNumber) + ComputeEnumSizeNoTag(value);
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode an
-        /// sfixed32 field, including the tag.
-        /// </summary>
-        public static int ComputeSFixed32Size(int fieldNumber, int value)
-        {
-            return ComputeTagSize(fieldNumber) + LittleEndian32Size;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode an
-        /// sfixed64 field, including the tag.
-        /// </summary>
-        public static int ComputeSFixed64Size(int fieldNumber, long value)
-        {
-            return ComputeTagSize(fieldNumber) + LittleEndian64Size;
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode an
-        /// sint32 field, including the tag.
-        /// </summary>
-        public static int ComputeSInt32Size(int fieldNumber, int value)
-        {
-            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size(EncodeZigZag32(value));
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode an
-        /// sint64 field, including the tag.
-        /// </summary>
-        public static int ComputeSInt64Size(int fieldNumber, long value)
-        {
-            return ComputeTagSize(fieldNumber) + ComputeRawVarint64Size(EncodeZigZag64(value));
-        }
-
-        /// <summary>
-        /// Compute the number of bytes that would be needed to encode a
-        /// double field, including the tag.
-        /// </summary>
-        public static int ComputeDoubleSizeNoTag(double value)
+        public static int ComputeDoubleSize(double value)
         {
             return LittleEndian64Size;
         }
@@ -242,7 +62,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// float field, including the tag.
         /// </summary>
-        public static int ComputeFloatSizeNoTag(float value)
+        public static int ComputeFloatSize(float value)
         {
             return LittleEndian32Size;
         }
@@ -251,7 +71,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// uint64 field, including the tag.
         /// </summary>
-        public static int ComputeUInt64SizeNoTag(ulong value)
+        public static int ComputeUInt64Size(ulong value)
         {
             return ComputeRawVarint64Size(value);
         }
@@ -260,7 +80,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode an
         /// int64 field, including the tag.
         /// </summary>
-        public static int ComputeInt64SizeNoTag(long value)
+        public static int ComputeInt64Size(long value)
         {
             return ComputeRawVarint64Size((ulong) value);
         }
@@ -269,7 +89,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode an
         /// int32 field, including the tag.
         /// </summary>
-        public static int ComputeInt32SizeNoTag(int value)
+        public static int ComputeInt32Size(int value)
         {
             if (value >= 0)
             {
@@ -286,7 +106,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// fixed64 field, including the tag.
         /// </summary>
-        public static int ComputeFixed64SizeNoTag(ulong value)
+        public static int ComputeFixed64Size(ulong value)
         {
             return LittleEndian64Size;
         }
@@ -295,7 +115,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// fixed32 field, including the tag.
         /// </summary>
-        public static int ComputeFixed32SizeNoTag(uint value)
+        public static int ComputeFixed32Size(uint value)
         {
             return LittleEndian32Size;
         }
@@ -304,7 +124,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// bool field, including the tag.
         /// </summary>
-        public static int ComputeBoolSizeNoTag(bool value)
+        public static int ComputeBoolSize(bool value)
         {
             return 1;
         }
@@ -313,7 +133,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// string field, including the tag.
         /// </summary>
-        public static int ComputeStringSizeNoTag(String value)
+        public static int ComputeStringSize(String value)
         {
             int byteArraySize = UTF8.GetByteCount(value);
             return ComputeRawVarint32Size((uint) byteArraySize) +
@@ -324,7 +144,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// group field, including the tag.
         /// </summary>
-        public static int ComputeGroupSizeNoTag(IMessage value)
+        public static int ComputeGroupSize(IMessage value)
         {
             return value.CalculateSize();
         }
@@ -333,7 +153,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode an
         /// embedded message field, including the tag.
         /// </summary>
-        public static int ComputeMessageSizeNoTag(IMessage value)
+        public static int ComputeMessageSize(IMessage value)
         {
             int size = value.CalculateSize();
             return ComputeRawVarint32Size((uint) size) + size;
@@ -343,7 +163,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// bytes field, including the tag.
         /// </summary>
-        public static int ComputeBytesSizeNoTag(ByteString value)
+        public static int ComputeBytesSize(ByteString value)
         {
             return ComputeRawVarint32Size((uint) value.Length) +
                    value.Length;
@@ -353,7 +173,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode a
         /// uint32 field, including the tag.
         /// </summary>
-        public static int ComputeUInt32SizeNoTag(uint value)
+        public static int ComputeUInt32Size(uint value)
         {
             return ComputeRawVarint32Size(value);
         }
@@ -363,17 +183,17 @@ namespace Google.Protobuf
         /// enum field, including the tag. The caller is responsible for
         /// converting the enum value to its numeric value.
         /// </summary>
-        public static int ComputeEnumSizeNoTag(int value)
+        public static int ComputeEnumSize(int value)
         {
             // Currently just a pass-through, but it's nice to separate it logically.
-            return ComputeInt32SizeNoTag(value);
+            return ComputeInt32Size(value);
         }
 
         /// <summary>
         /// Compute the number of bytes that would be needed to encode an
         /// sfixed32 field, including the tag.
         /// </summary>
-        public static int ComputeSFixed32SizeNoTag(int value)
+        public static int ComputeSFixed32Size(int value)
         {
             return LittleEndian32Size;
         }
@@ -382,7 +202,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode an
         /// sfixed64 field, including the tag.
         /// </summary>
-        public static int ComputeSFixed64SizeNoTag(long value)
+        public static int ComputeSFixed64Size(long value)
         {
             return LittleEndian64Size;
         }
@@ -391,7 +211,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode an
         /// sint32 field, including the tag.
         /// </summary>
-        public static int ComputeSInt32SizeNoTag(int value)
+        public static int ComputeSInt32Size(int value)
         {
             return ComputeRawVarint32Size(EncodeZigZag32(value));
         }
@@ -400,7 +220,7 @@ namespace Google.Protobuf
         /// Compute the number of bytes that would be needed to encode an
         /// sint64 field, including the tag.
         /// </summary>
-        public static int ComputeSInt64SizeNoTag(long value)
+        public static int ComputeSInt64Size(long value)
         {
             return ComputeRawVarint64Size(EncodeZigZag64(value));
         }

+ 163 - 454
csharp/src/ProtocolBuffers/CodedOutputStream.cs

@@ -143,248 +143,12 @@ namespace Google.Protobuf
             }
         }
 
-        #region Writing of tags and fields
-        /// <summary>
-        /// Writes a double field value, including tag, to the stream.
-        /// </summary>
-        public void WriteDouble(int fieldNumber, double value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
-            WriteDoubleNoTag(value);
-        }
-
-        /// <summary>
-        /// Writes a float field value, including tag, to the stream.
-        /// </summary>
-        public void WriteFloat(int fieldNumber, float value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
-            WriteFloatNoTag(value);
-        }
-
-        /// <summary>
-        /// Writes a uint64 field value, including tag, to the stream.
-        /// </summary>
-        public void WriteUInt64(int fieldNumber, ulong value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteRawVarint64(value);
-        }
-
-        /// <summary>
-        /// Writes an int64 field value, including tag, to the stream.
-        /// </summary>
-        public void WriteInt64(int fieldNumber, long value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteRawVarint64((ulong) value);
-        }
-
-        /// <summary>
-        /// Writes an int32 field value, including tag, to the stream.
-        /// </summary>
-        public void WriteInt32(int fieldNumber, int value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            if (value >= 0)
-            {
-                WriteRawVarint32((uint) value);
-            }
-            else
-            {
-                // Must sign-extend.
-                WriteRawVarint64((ulong) value);
-            }
-        }
-
-        /// <summary>
-        /// Writes a fixed64 field value, including tag, to the stream.
-        /// </summary>
-        public void WriteFixed64(int fieldNumber, ulong value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
-            WriteRawLittleEndian64(value);
-        }
-
-        /// <summary>
-        /// Writes a fixed32 field value, including tag, to the stream.
-        /// </summary>
-        public void WriteFixed32(int fieldNumber, uint value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
-            WriteRawLittleEndian32(value);
-        }
-
-        /// <summary>
-        /// Writes a bool field value, including tag, to the stream.
-        /// </summary>
-        public void WriteBool(int fieldNumber, bool value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteRawByte(value ? (byte) 1 : (byte) 0);
-        }
-
-        /// <summary>
-        /// Writes a string field value, including tag, to the stream.
-        /// </summary>
-        public void WriteString(int fieldNumber, string value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
-            // Optimise the case where we have enough space to write
-            // the string directly to the buffer, which should be common.
-            int length = UTF8.GetByteCount(value);
-            WriteRawVarint32((uint) length);
-            if (limit - position >= length)
-            {
-                if (length == value.Length) // Must be all ASCII...
-                {
-                                for (int i = 0; i < length; i++)
-                                {
-                        buffer[position + i] = (byte)value[i];
-                    }
-                }
-                else
-                {
-                    UTF8.GetBytes(value, 0, value.Length, buffer, position);
-                }
-                position += length;
-            }
-            else
-            {
-                byte[] bytes = UTF8.GetBytes(value);
-                WriteRawBytes(bytes);
-            }
-        }
-
-        /// <summary>
-        /// Writes a group field value, including tag, to the stream.
-        /// </summary>
-        public void WriteGroup(int fieldNumber, IMessage value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.StartGroup);
-            value.WriteTo(this);
-            WriteTag(fieldNumber, WireFormat.WireType.EndGroup);
-        }
-
-        public void WriteMessage(int fieldNumber, IMessage value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
-            WriteRawVarint32((uint) value.CalculateSize());
-            value.WriteTo(this);
-        }
-
-        public void WriteBytes(int fieldNumber, ByteString value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
-            WriteRawVarint32((uint) value.Length);
-            value.WriteRawBytesTo(this);
-        }
-
-        public void WriteUInt32(int fieldNumber, uint value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteRawVarint32(value);
-        }
-
-        public void WriteEnum(int fieldNumber, int value)
-        {
-            // Currently just a pass-through, but it's nice to separate it logically from WriteInt32.
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteInt32NoTag(value);
-        }
-
-        public void WriteSFixed32(int fieldNumber, int value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
-            WriteRawLittleEndian32((uint) value);
-        }
-
-        public void WriteSFixed64(int fieldNumber, long value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
-            WriteRawLittleEndian64((ulong) value);
-        }
-
-        public void WriteSInt32(int fieldNumber, int value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteRawVarint32(EncodeZigZag32(value));
-        }
-
-        public void WriteSInt64(int fieldNumber, long value)
-        {
-            WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteRawVarint64(EncodeZigZag64(value));
-        }
-        #endregion
-
         #region Writing of values without tags
-        // TODO(jonskeet): Remove this?
-        public void WriteFieldNoTag(FieldType fieldType, object value)
-        {
-            switch (fieldType)
-            {
-                case FieldType.String:
-                    WriteStringNoTag((string) value);
-                    break;
-                case FieldType.Message:
-                    WriteMessageNoTag((IMessage) value);
-                    break;
-                case FieldType.Group:
-                    WriteGroupNoTag((IMessage) value);
-                    break;
-                case FieldType.Bytes:
-                    WriteBytesNoTag((ByteString) value);
-                    break;
-                case FieldType.Bool:
-                    WriteBoolNoTag((bool) value);
-                    break;
-                case FieldType.Enum:
-                    WriteEnumNoTag((int) value);
-                    break;
-                case FieldType.Int32:
-                    WriteInt32NoTag((int) value);
-                    break;
-                case FieldType.Int64:
-                    WriteInt64NoTag((long) value);
-                    break;
-                case FieldType.UInt32:
-                    WriteUInt32NoTag((uint) value);
-                    break;
-                case FieldType.UInt64:
-                    WriteUInt64NoTag((ulong) value);
-                    break;
-                case FieldType.SInt32:
-                    WriteSInt32NoTag((int) value);
-                    break;
-                case FieldType.SInt64:
-                    WriteSInt64NoTag((long) value);
-                    break;
-                case FieldType.Fixed32:
-                    WriteFixed32NoTag((uint) value);
-                    break;
-                case FieldType.Fixed64:
-                    WriteFixed64NoTag((ulong) value);
-                    break;
-                case FieldType.SFixed32:
-                    WriteSFixed32NoTag((int) value);
-                    break;
-                case FieldType.SFixed64:
-                    WriteSFixed64NoTag((long) value);
-                    break;
-                case FieldType.Double:
-                    WriteDoubleNoTag((double) value);
-                    break;
-                case FieldType.Float:
-                    WriteFloatNoTag((float) value);
-                    break;
-            }
-        }
 
         /// <summary>
         /// Writes a double field value, including tag, to the stream.
         /// </summary>
-        public void WriteDoubleNoTag(double value)
+        public void WriteDouble(double value)
         {
             WriteRawLittleEndian64((ulong)FrameworkPortability.DoubleToInt64(value));
         }
@@ -392,7 +156,7 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes a float field value, without a tag, to the stream.
         /// </summary>
-        public void WriteFloatNoTag(float value)
+        public void WriteFloat(float value)
         {
             byte[] rawBytes = BitConverter.GetBytes(value);
             if (!BitConverter.IsLittleEndian)
@@ -416,7 +180,7 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes a uint64 field value, without a tag, to the stream.
         /// </summary>
-        public void WriteUInt64NoTag(ulong value)
+        public void WriteUInt64(ulong value)
         {
             WriteRawVarint64(value);
         }
@@ -424,7 +188,7 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes an int64 field value, without a tag, to the stream.
         /// </summary>
-        public void WriteInt64NoTag(long value)
+        public void WriteInt64(long value)
         {
             WriteRawVarint64((ulong) value);
         }
@@ -432,7 +196,7 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes an int32 field value, without a tag, to the stream.
         /// </summary>
-        public void WriteInt32NoTag(int value)
+        public void WriteInt32(int value)
         {
             if (value >= 0)
             {
@@ -448,7 +212,7 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes a fixed64 field value, without a tag, to the stream.
         /// </summary>
-        public void WriteFixed64NoTag(ulong value)
+        public void WriteFixed64(ulong value)
         {
             WriteRawLittleEndian64(value);
         }
@@ -456,7 +220,7 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes a fixed32 field value, without a tag, to the stream.
         /// </summary>
-        public void WriteFixed32NoTag(uint value)
+        public void WriteFixed32(uint value)
         {
             WriteRawLittleEndian32(value);
         }
@@ -464,7 +228,7 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes a bool field value, without a tag, to the stream.
         /// </summary>
-        public void WriteBoolNoTag(bool value)
+        public void WriteBool(bool value)
         {
             WriteRawByte(value ? (byte) 1 : (byte) 0);
         }
@@ -472,485 +236,440 @@ namespace Google.Protobuf
         /// <summary>
         /// Writes a string field value, without a tag, to the stream.
         /// </summary>
-        public void WriteStringNoTag(string value)
+        public void WriteString(string value)
         {
             // Optimise the case where we have enough space to write
             // the string directly to the buffer, which should be common.
-            int length = Encoding.UTF8.GetByteCount(value);
-            WriteRawVarint32((uint) length);
+            int length = UTF8.GetByteCount(value);
+            WriteRawVarint32((uint)length);
             if (limit - position >= length)
             {
-                Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, position);
+                if (length == value.Length) // Must be all ASCII...
+                {
+                    for (int i = 0; i < length; i++)
+                    {
+                        buffer[position + i] = (byte)value[i];
+                    }
+                }
+                else
+                {
+                    UTF8.GetBytes(value, 0, value.Length, buffer, position);
+                }
                 position += length;
             }
             else
             {
-                byte[] bytes = Encoding.UTF8.GetBytes(value);
+                byte[] bytes = UTF8.GetBytes(value);
                 WriteRawBytes(bytes);
             }
         }
 
-        /// <summary>
-        /// Writes a group field value, without a tag, to the stream.
-        /// </summary>
-        public void WriteGroupNoTag(IMessage value)
-        {
-            value.WriteTo(this);
-        }
-
-        public void WriteMessageNoTag(IMessage value)
+        public void WriteMessage(IMessage value)
         {
             WriteRawVarint32((uint) value.CalculateSize());
             value.WriteTo(this);
         }
 
-        public void WriteBytesNoTag(ByteString value)
+        public void WriteBytes(ByteString value)
         {
             WriteRawVarint32((uint) value.Length);
             value.WriteRawBytesTo(this);
         }
 
-        public void WriteUInt32NoTag(uint value)
+        public void WriteUInt32(uint value)
         {
             WriteRawVarint32(value);
         }
 
-        public void WriteEnumNoTag(int value)
+        public void WriteEnum(int value)
         {
-            WriteInt32NoTag(value);
+            WriteInt32(value);
         }
 
-        public void WriteSFixed32NoTag(int value)
+        public void WriteSFixed32(int value)
         {
             WriteRawLittleEndian32((uint) value);
         }
 
-        public void WriteSFixed64NoTag(long value)
+        public void WriteSFixed64(long value)
         {
             WriteRawLittleEndian64((ulong) value);
         }
 
-        public void WriteSInt32NoTag(int value)
+        public void WriteSInt32(int value)
         {
             WriteRawVarint32(EncodeZigZag32(value));
         }
 
-        public void WriteSInt64NoTag(long value)
+        public void WriteSInt64(long value)
         {
             WriteRawVarint64(EncodeZigZag64(value));
         }
 
         #endregion
 
-        #region Write array members
+        #region Write array members, with fields.
         public void WriteMessageArray<T>(int fieldNumber, RepeatedField<T> list)
             where T : IMessage
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (T value in list)
             {
-                WriteMessage(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+                WriteMessage(value);
             }
         }
 
         public void WriteStringArray(int fieldNumber, RepeatedField<string> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteString(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+                WriteString(value);
             }
         }
 
         public void WriteBytesArray(int fieldNumber, RepeatedField<ByteString> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteBytes(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+                WriteBytes(value);
             }
         }
 
         public void WriteBoolArray(int fieldNumber, RepeatedField<bool> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteBool(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Varint);
+                WriteBool(value);
             }
         }
 
         public void WriteInt32Array(int fieldNumber, RepeatedField<int> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteInt32(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Varint);
+                WriteInt32(value);
             }
         }
 
         public void WriteSInt32Array(int fieldNumber, RepeatedField<int> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteSInt32(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Varint);
+                WriteSInt32(value);
             }
         }
 
         public void WriteUInt32Array(int fieldNumber, RepeatedField<uint> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteUInt32(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Varint);
+                WriteUInt32(value);
             }
         }
 
         public void WriteFixed32Array(int fieldNumber, RepeatedField<uint> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteFixed32(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
+                WriteFixed32(value);
             }
         }
 
         public void WriteSFixed32Array(int fieldNumber, RepeatedField<int> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteSFixed32(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
+                WriteSFixed32(value);
             }
         }
 
         public void WriteInt64Array(int fieldNumber, RepeatedField<long> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteInt64(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
+                WriteInt64(value);
             }
         }
 
         public void WriteSInt64Array(int fieldNumber, RepeatedField<long> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteSInt64(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Varint);
+                WriteSInt64(value);
             }
         }
 
         public void WriteUInt64Array(int fieldNumber, RepeatedField<ulong> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteUInt64(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Varint);
+                WriteUInt64(value);
             }
         }
 
         public void WriteFixed64Array(int fieldNumber, RepeatedField<ulong> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteFixed64(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
+                WriteFixed64(value);
             }
         }
 
         public void WriteSFixed64Array(int fieldNumber, RepeatedField<long> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteSFixed64(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
+                WriteSFixed64(value);
             }
         }
 
         public void WriteDoubleArray(int fieldNumber, RepeatedField<double> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteDouble(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Fixed64);
+                WriteDouble(value);
             }
         }
 
         public void WriteFloatArray(int fieldNumber, RepeatedField<float> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             foreach (var value in list)
             {
-                WriteFloat(fieldNumber, value);
+                WriteTag(fieldNumber, WireFormat.WireType.Fixed32);
+                WriteFloat(value);
             }
         }
 
         public void WriteEnumArray<T>(int fieldNumber, RepeatedField<T> list)
             where T : struct, IComparable, IFormattable
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             // Bit of a hack, to access the values as ints
             var iterator = list.GetInt32Enumerator();
             while (iterator.MoveNext())
             {
-                WriteEnum(fieldNumber, iterator.Current);
+                WriteTag(fieldNumber, WireFormat.WireType.Varint);
+                WriteEnum(iterator.Current);
             }
         }
 
         #endregion
 
+        #region Raw tag writing
+        /// <summary>
+        /// Encodes and writes a tag.
+        /// </summary>
+        public void WriteTag(int fieldNumber, WireFormat.WireType type)
+        {
+            WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
+        }
+
+        /// <summary>
+        /// Writes the given single-byte tag directly to the stream.
+        /// </summary>
+        public void WriteRawTag(byte b1)
+        {
+            WriteRawByte(b1);
+        }
+
+        /// <summary>
+        /// Writes the given two-byte tag directly to the stream.
+        /// </summary>
+        public void WriteRawTag(byte b1, byte b2)
+        {
+            WriteRawByte(b1);
+            WriteRawByte(b2);
+        }
+
+        /// <summary>
+        /// Writes the given three-byte tag directly to the stream.
+        /// </summary>
+        public void WriteRawTag(byte b1, byte b2, byte b3)
+        {
+            WriteRawByte(b1);
+            WriteRawByte(b2);
+            WriteRawByte(b3);
+        }
+
+        /// <summary>
+        /// Writes the given four-byte tag directly to the stream.
+        /// </summary>
+        public void WriteRawTag(byte b1, byte b2, byte b3, byte b4)
+        {
+            WriteRawByte(b1);
+            WriteRawByte(b2);
+            WriteRawByte(b3);
+            WriteRawByte(b4);
+        }
+
+        /// <summary>
+        /// Writes the given five-byte tag directly to the stream.
+        /// </summary>
+        public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5)
+        {
+            WriteRawByte(b1);
+            WriteRawByte(b2);
+            WriteRawByte(b3);
+            WriteRawByte(b4);
+            WriteRawByte(b5);
+        }
+        #endregion
+
         #region Write packed array members
         // TODO(jonskeet): A lot of these are really inefficient, due to method group conversions. Fix!
-        public void WritePackedBoolArray(int fieldNumber, RepeatedField<bool> list)
+        // (Alternatively, add extension methods to RepeatedField, accepting the Write* methods via delegates too.)
+        public void WritePackedBoolArray(RepeatedField<bool> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             uint size = (uint)list.Count;
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteBoolNoTag(value);
+                WriteBool(value);
             }
         }
 
-        public void WritePackedInt32Array(int fieldNumber, RepeatedField<int> list)
+        public void WritePackedInt32Array(RepeatedField<int> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
-            uint size = list.CalculateSize(ComputeInt32SizeNoTag);
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            uint size = list.CalculateSize(ComputeInt32Size);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteInt32NoTag(value);
+                WriteInt32(value);
             }
         }
 
-        public void WritePackedSInt32Array(int fieldNumber, RepeatedField<int> list)
+        public void WritePackedSInt32Array(RepeatedField<int> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
-            uint size = list.CalculateSize(ComputeSInt32SizeNoTag);
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            uint size = list.CalculateSize(ComputeSInt32Size);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteSInt32NoTag(value);
+                WriteSInt32(value);
             }
         }
 
-        public void WritePackedUInt32Array(int fieldNumber, RepeatedField<uint> list)
+        public void WritePackedUInt32Array(RepeatedField<uint> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
-            uint size = list.CalculateSize(ComputeUInt32SizeNoTag);
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            uint size = list.CalculateSize(ComputeUInt32Size);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteUInt32NoTag(value);
+                WriteUInt32(value);
             }
         }
 
-        public void WritePackedFixed32Array(int fieldNumber, RepeatedField<uint> list)
+        public void WritePackedFixed32Array(RepeatedField<uint> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             uint size = (uint) list.Count * 4;
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteFixed32NoTag(value);
+                WriteFixed32(value);
             }
         }
 
-        public void WritePackedSFixed32Array(int fieldNumber, RepeatedField<int> list)
+        public void WritePackedSFixed32Array(RepeatedField<int> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             uint size = (uint) list.Count * 4;
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteSFixed32NoTag(value);
+                WriteSFixed32(value);
             }
         }
 
-        public void WritePackedInt64Array(int fieldNumber, RepeatedField<long> list)
+        public void WritePackedInt64Array(RepeatedField<long> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
-            uint size = list.CalculateSize(ComputeInt64SizeNoTag);
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            uint size = list.CalculateSize(ComputeInt64Size);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteInt64NoTag(value);
+                WriteInt64(value);
             }
         }
 
-        public void WritePackedSInt64Array(int fieldNumber, RepeatedField<long> list)
+        public void WritePackedSInt64Array(RepeatedField<long> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
-            uint size = list.CalculateSize(ComputeSInt64SizeNoTag);
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            uint size = list.CalculateSize(ComputeSInt64Size);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteSInt64NoTag(value);
+                WriteSInt64(value);
             }
         }
 
-        public void WritePackedUInt64Array(int fieldNumber, RepeatedField<ulong> list)
+        public void WritePackedUInt64Array(RepeatedField<ulong> list)
         {
             if (list.Count == 0)
             {
                 return;
             }
-            uint size = list.CalculateSize(ComputeUInt64SizeNoTag);
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
+            uint size = list.CalculateSize(ComputeUInt64Size);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteUInt64NoTag(value);
+                WriteUInt64(value);
             }
         }
 
-        public void WritePackedFixed64Array(int fieldNumber, RepeatedField<ulong> list)
+        public void WritePackedFixed64Array(RepeatedField<ulong> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             uint size = (uint) list.Count * 8;
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteFixed64NoTag(value);
+                WriteFixed64(value);
             }
         }
 
-        public void WritePackedSFixed64Array(int fieldNumber, RepeatedField<long> list)
+        public void WritePackedSFixed64Array(RepeatedField<long> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             uint size = (uint) list.Count * 8;
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteSFixed64NoTag(value);
+                WriteSFixed64(value);
             }
         }
 
-        public void WritePackedDoubleArray(int fieldNumber, RepeatedField<double> list)
+        public void WritePackedDoubleArray(RepeatedField<double> list)
         {
-            if (list.Count == 0)
-            {
-                return;
-            }
             uint size = (uint) list.Count * 8;
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteDoubleNoTag(value);
+                WriteDouble(value);
             }
         }
 
-        public void WritePackedFloatArray(int fieldNumber, RepeatedField<float> list)
+        public void WritePackedFloatArray(RepeatedField<float> list)
         {
             if (list.Count == 0)
             {
                 return;
             }
             uint size = (uint) list.Count * 4;
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             foreach (var value in list)
             {
-                WriteFloatNoTag(value);
+                WriteFloat(value);
             }
         }
 
-        public void WritePackedEnumArray<T>(int fieldNumber, RepeatedField<T> list)
+        public void WritePackedEnumArray<T>(RepeatedField<T> list)
             where T : struct, IComparable, IFormattable
         {
             if (list.Count == 0)
@@ -962,29 +681,19 @@ namespace Google.Protobuf
             uint size = 0;
             while (iterator.MoveNext())
             {
-                size += (uint) ComputeEnumSizeNoTag(iterator.Current);
+                size += (uint) ComputeEnumSize(iterator.Current);
             }
             iterator.Reset();
-            WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteRawVarint32(size);
             while (iterator.MoveNext())
             {
-                WriteEnumNoTag(iterator.Current);
+                WriteEnum(iterator.Current);
             }
         }
 
         #endregion
 
         #region Underlying writing primitives
-
-        /// <summary>
-        /// Encodes and writes a tag.
-        /// </summary>
-        public void WriteTag(int fieldNumber, WireFormat.WireType type)
-        {
-            WriteRawVarint32(WireFormat.MakeTag(fieldNumber, type));
-        }
-
         /// <summary>
         /// Writes a 32 bit value as a varint. The fast route is taken when
         /// there's enough buffer space left to whizz through without checking

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 255 - 164
csharp/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs


+ 6 - 4
src/google/protobuf/compiler/csharp/csharp_enum_field.cc

@@ -61,7 +61,8 @@ void EnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
 void EnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(variables_,
     "if ($has_property_check$) {\n"
-    "  output.WriteEnum($number$, (int) $property_name$);\n"
+    "  output.WriteRawTag($tag_bytes$);\n"
+    "  output.WriteEnum((int) $property_name$);\n"
     "}\n");
 }
 
@@ -69,7 +70,7 @@ void EnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-      "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (int) $property_name$);\n"
+      "  size += $tag_size$ + pb::CodedOutputStream.ComputeEnumSize((int) $property_name$);\n"
     "}\n");
 }
 
@@ -93,7 +94,8 @@ void EnumOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.WriteEnum($number$, (int) $property_name$);\n"
+    "  output.WriteRawTag($tag_bytes$);\n"
+    "  output.WriteEnum((int) $property_name$);\n"
     "}\n");
 }
 
@@ -101,7 +103,7 @@ void EnumOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (int) $property_name$);\n"
+    "  size += $tag_size$ + pb::CodedOutputStream.ComputeEnumSize((int) $property_name$);\n"
     "}\n");
 }
 

+ 13 - 2
src/google/protobuf/compiler/csharp/csharp_field_base.cc

@@ -35,6 +35,7 @@
 #include <google/protobuf/compiler/plugin.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/stubs/strutil.h>
@@ -55,8 +56,18 @@ void FieldGeneratorBase::SetCommonFieldVariables(
   // Note: this will be valid even though the tag emitted for packed and unpacked versions of
   // repeated fields varies by wire format. The wire format is encoded in the bottom 3 bits, which
   // never effects the tag size.
-  int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
-  (*variables)["tag_size"] = SimpleItoa(tagSize);
+  int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
+  uint tag = internal::WireFormat::MakeTag(descriptor_);
+  uint8 tag_array[5];
+  io::CodedOutputStream::WriteTagToArray(tag, tag_array);
+  string tag_bytes = SimpleItoa(tag_array[0]);
+  for (int i = 1; i < tag_size; i++) {
+    tag_bytes += ", " + SimpleItoa(tag_array[i]);
+  }
+
+  (*variables)["tag_size"] = SimpleItoa(tag_size);
+  (*variables)["tag_bytes"] = tag_bytes;
+
   (*variables)["property_name"] = property_name();
   (*variables)["type_name"] = type_name();
   (*variables)["name"] = name();

+ 3 - 3
src/google/protobuf/compiler/csharp/csharp_message_field.cc

@@ -92,11 +92,11 @@ void MessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
 }
 
 void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
-  // TODO(jonskeet): Why are we using array access instead of a literal here?
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.WriteMessage($number$, $property_name$);\n"
+    "  output.WriteRawTag($tag_bytes$);\n"
+    "  output.WriteMessage($property_name$);\n"
     "}\n");
 }
 
@@ -104,7 +104,7 @@ void MessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  size += pb::CodedOutputStream.ComputeMessageSize($number$, $property_name$);\n"
+    "  size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($property_name$);\n"
     "}\n");
 }
 

+ 18 - 5
src/google/protobuf/compiler/csharp/csharp_primitive_field.cc

@@ -105,16 +105,29 @@ void PrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.Write$capitalized_type_name$($number$, $property_name$);\n"
+    "  output.WriteRawTag($tag_bytes$);\n"
+    "  output.Write$capitalized_type_name$($property_name$);\n"
     "}\n");
 }
 
 void PrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if ($has_property_check$) {\n"
-    "  size += pb::CodedOutputStream.Compute$capitalized_type_name$Size($number$, $property_name$);\n"
-    "}\n");
+    "if ($has_property_check$) {\n");
+  printer->Indent();
+  int fixedSize = GetFixedSize(descriptor_->type());
+  if (fixedSize == -1) {
+    printer->Print(
+      variables_,
+      "size += $tag_size$ + pb::CodedOutputStream.Compute$capitalized_type_name$Size($property_name$);\n");
+  } else {
+    printer->Print(
+      "size += $tag_size$ + $fixed_size$;\n",
+      "fixed_size", SimpleItoa(fixedSize),
+      "tag_size", variables_["tag_size"]);
+  }    
+  printer->Outdent();
+  printer->Print("}\n");
 }
 
 void PrimitiveFieldGenerator::WriteHash(io::Printer* printer) {
@@ -173,7 +186,7 @@ void PrimitiveOneofFieldGenerator::WriteToString(io::Printer* printer) {
 void PrimitiveOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
     printer->Print(
       variables_,
-      "$property_name$ = input.Read$capitalized_type_name$()\n;");
+      "$property_name$ = input.Read$capitalized_type_name$();\n");
 }
 
 }  // namespace csharp

+ 16 - 6
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc

@@ -82,9 +82,20 @@ void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
 void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if ($name$_.Count > 0) {\n"
-    "  output.Write$packed$EnumArray($number$, $name$_);\n"
-    "}\n");
+    "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");
 }
 
 void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
@@ -97,14 +108,13 @@ void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer
   printer->Print(
     variables_,
     "foreach ($type_name$ element in $name$_) {\n"
-    "  dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);\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$;\n"
-      "size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);\n",
+      "size += $tag_size$ + pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);\n",
       "tag_size", SimpleItoa(tagSize));
   } else {
     printer->Print(

+ 4 - 4
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc

@@ -79,8 +79,8 @@ void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
 }
 
 void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
-  // TODO(jonskeet): Originally, this checked for Count > 0 first.
-  // The Write* call should make that cheap though - no need to generate it every time.
+  // 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"
@@ -89,13 +89,13 @@ void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* print
 }
 
 void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
-  // TODO(jonskeet): Put this into CodedOutputStream.
   printer->Print(
     variables_,
     "if ($name$_.Count > 0) {\n"
     "  foreach ($type_name$ element in $name$_) {\n"
-    "    size += pb::CodedOutputStream.ComputeMessageSize($number$, element);\n"
+    "    size += pb::CodedOutputStream.ComputeMessageSize(element);\n"
     "  }\n"
+    "  size += $tag_size$ * $name$_.Count;\n"
     "}\n");
 }
 

+ 16 - 5
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc

@@ -82,9 +82,20 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
     io::Printer* printer) {
   printer->Print(
     variables_,
-    "if ($name$_.Count > 0) {\n"
-    "  output.Write$packed$$capitalized_type_name$Array($number$, $name$_);\n"
-    "}\n");
+    "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");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
@@ -100,7 +111,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
     printer->Print(
       variables_,
       "foreach ($type_name$ element in $name$_) {\n"
-      "  dataSize += pb::CodedOutputStream.Compute$capitalized_type_name$SizeNoTag(element);\n"
+      "  dataSize += pb::CodedOutputStream.Compute$capitalized_type_name$Size(element);\n"
       "}\n");
   } else {
     printer->Print(
@@ -111,7 +122,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
   int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
   if (descriptor_->is_packed()) {
     printer->Print(
-      "size += $tag_size$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);\n",
+      "size += $tag_size$ + pb::CodedOutputStream.ComputeInt32Size(dataSize);\n",
       "tag_size", SimpleItoa(tagSize));
   } else {
     printer->Print(

+ 1 - 1
src/google/protobuf/wire_format.h

@@ -290,7 +290,7 @@ class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper {
 
 inline WireFormatLite::WireType WireFormat::WireTypeForField(
     const FieldDescriptor* field) {
-  if (field->options().packed()) {
+  if (field->is_packed()) {
     return WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
   } else {
     return WireTypeForFieldType(field->type());

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels