From 8c13fe77bce990ad70993250223fc2517c9e3c3d Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Mon, 24 Sep 2018 20:40:38 -0500 Subject: [PATCH 01/11] Group library changes --- .../src/Google.Protobuf/CodedInputStream.cs | 56 ++++++++++++++++++- .../src/Google.Protobuf/CodedOutputStream.cs | 9 +++ csharp/src/Google.Protobuf/FieldCodec.cs | 35 ++++++++++-- csharp/src/Google.Protobuf/UnknownField.cs | 29 +++++++++- csharp/src/Google.Protobuf/UnknownFieldSet.cs | 8 ++- 5 files changed, 130 insertions(+), 7 deletions(-) diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs index 0a829545e257..6e6406f0cda6 100644 --- a/csharp/src/Google.Protobuf/CodedInputStream.cs +++ b/csharp/src/Google.Protobuf/CodedInputStream.cs @@ -108,6 +108,7 @@ public sealed class CodedInputStream : IDisposable /// The absolute position of the end of the current message. /// private int currentLimit = int.MaxValue; + private uint tagLimit = uint.MaxValue; private int recursionDepth = 0; @@ -373,7 +374,7 @@ public uint ReadTag() if (IsAtEnd) { lastTag = 0; - return 0; // This is the only case in which we return 0. + return 0; } lastTag = ReadRawVarint32(); @@ -383,6 +384,10 @@ public uint ReadTag() // If we actually read a tag with a field of 0, that's not a valid tag. throw InvalidProtocolBufferException.InvalidTag(); } + if (ReachedLimit) + { + return 0; + } return lastTag; } @@ -591,6 +596,26 @@ public void ReadMessage(IMessage builder) PopLimit(oldLimit); } + /// + /// Reads an embedded group field from the stream. + /// + public void ReadGroup(IMessage builder) + { + if (recursionDepth >= recursionLimit) + { + throw InvalidProtocolBufferException.RecursionLimitExceeded(); + } + uint oldTag = PushTag(); + ++recursionDepth; + builder.MergeFrom(this); + if (!ReachedTagLimit) + { + throw InvalidProtocolBufferException.TruncatedMessage(); + } + --recursionDepth; + PopTag(oldTag); + } + /// /// Reads a bytes field value from the stream. /// @@ -953,6 +978,19 @@ internal int PushLimit(int byteLimit) return oldLimit; } + /// + /// Sets tagLimit to the limit calculated by the last tag. + /// This is called when descending into a group message. The previous limit is returns. + /// + /// The old limit + internal uint PushTag() + { + uint oldLimit = tagLimit; + uint newLimit = WireFormat.MakeTag(WireFormat.GetTagFieldNumber(LastTag), WireFormat.WireType.EndGroup); + tagLimit = newLimit; + return oldLimit; + } + private void RecomputeBufferSizeAfterLimit() { bufferSize += bufferSizeAfterLimit; @@ -978,6 +1016,14 @@ internal void PopLimit(int oldLimit) RecomputeBufferSizeAfterLimit(); } + /// + /// Discards the current limit, returning the previous limit + /// + internal void PopTag(uint oldTag) + { + tagLimit = oldTag; + } + /// /// Returns whether or not all the data before the limit has been read. /// @@ -995,6 +1041,14 @@ internal bool ReachedLimit } } + internal bool ReachedTagLimit + { + get + { + return tagLimit == lastTag; + } + } + /// /// Returns true if the stream has reached the end of the input. This is the /// case if either the end of the underlying input source has been reached or diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.cs b/csharp/src/Google.Protobuf/CodedOutputStream.cs index 6211aac32cb1..f9ad29086bda 100644 --- a/csharp/src/Google.Protobuf/CodedOutputStream.cs +++ b/csharp/src/Google.Protobuf/CodedOutputStream.cs @@ -303,6 +303,15 @@ public void WriteMessage(IMessage value) value.WriteTo(this); } + /// + /// Writes a group, without a tag, to the stream. + /// + /// The value to write + public void WriteGroup(IMessage value) + { + value.WriteTo(this); + } + /// /// Write a byte string, without a tag, to the stream. /// The data is length-prefixed. diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs index a11f2420e313..0d0983869f7c 100644 --- a/csharp/src/Google.Protobuf/FieldCodec.cs +++ b/csharp/src/Google.Protobuf/FieldCodec.cs @@ -225,6 +225,19 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func output.WriteMessage(value), message => CodedOutputStream.ComputeMessageSize(message), tag); } + /// + /// Retrieves a codec suitable for a group field with the given tag. + /// + /// The start group tag. + /// The end group tag. + /// A parser to use for the group message type. + /// A codec for given tag + public static FieldCodec ForGroup(uint startTag, uint endTag, MessageParser parser) where T : IMessage + { + return new FieldCodec(input => { T message = parser.CreateTemplate(); input.ReadGroup(message); return message; }, + (output, value) => output.WriteGroup(value), message => CodedOutputStream.ComputeGroupSize(message), startTag, endTag); + } + /// /// Creates a codec for a wrapper type of a class - which must be string or ByteString. /// @@ -235,7 +248,7 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func WrapperCodecs.Read(input, nestedCodec), (output, value) => WrapperCodecs.Write(output, value, nestedCodec), value => WrapperCodecs.CalculateSize(value, nestedCodec), - tag, + tag, 0, null); // Default value for the wrapper } @@ -250,7 +263,7 @@ public static FieldCodec ForEnum(uint tag, Func toInt32, Func WrapperCodecs.Read(input, nestedCodec), (output, value) => WrapperCodecs.Write(output, value.Value, nestedCodec), value => value == null ? 0 : WrapperCodecs.CalculateSize(value.Value, nestedCodec), - tag, + tag, 0, null); // Default value for the wrapper } @@ -399,6 +412,14 @@ static FieldCodec() /// internal uint Tag { get; } + /// + /// Gets the end tag of the codec or 0 if there is no end tag + /// + /// + /// The end tag of the codec. + /// + internal uint EndTag { get; } + /// /// Default value for this codec. Usually the same for every instance of the same type, but /// for string/ByteString wrapper fields the codec's default value is null, whereas for @@ -415,7 +436,7 @@ static FieldCodec() Func reader, Action writer, int fixedSize, - uint tag) : this(reader, writer, _ => fixedSize, tag) + uint tag) : this(reader, writer, _ => fixedSize, 0, tag) { FixedSize = fixedSize; } @@ -424,7 +445,8 @@ static FieldCodec() Func reader, Action writer, Func sizeCalculator, - uint tag) : this(reader, writer, sizeCalculator, tag, DefaultDefault) + uint tag, + uint endTag = 0) : this(reader, writer, sizeCalculator, tag, endTag, DefaultDefault) { } @@ -433,6 +455,7 @@ static FieldCodec() Action writer, Func sizeCalculator, uint tag, + uint endTag, T defaultValue) { ValueReader = reader; @@ -455,6 +478,10 @@ public void WriteTagAndValue(CodedOutputStream output, T value) { output.WriteTag(Tag); ValueWriter(output, value); + if (EndTag != 0) + { + output.WriteTag(EndTag); + } } } diff --git a/csharp/src/Google.Protobuf/UnknownField.cs b/csharp/src/Google.Protobuf/UnknownField.cs index 0d6eed6357a8..2b13fdb3ec6a 100644 --- a/csharp/src/Google.Protobuf/UnknownField.cs +++ b/csharp/src/Google.Protobuf/UnknownField.cs @@ -55,6 +55,7 @@ internal sealed class UnknownField private List fixed32List; private List fixed64List; private List lengthDelimitedList; + private List groupList; /// /// Creates a new UnknownField. @@ -77,7 +78,8 @@ public override bool Equals(object other) && Lists.Equals(varintList, otherField.varintList) && Lists.Equals(fixed32List, otherField.fixed32List) && Lists.Equals(fixed64List, otherField.fixed64List) - && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList); + && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList) + && Lists.Equals(groupList, otherField.groupList); } /// @@ -90,6 +92,7 @@ public override int GetHashCode() hash = hash * 47 + Lists.GetHashCode(fixed32List); hash = hash * 47 + Lists.GetHashCode(fixed64List); hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList); + hash = hash * 47 + Lists.GetHashCode(groupList); return hash; } @@ -133,6 +136,15 @@ internal void WriteTo(int fieldNumber, CodedOutputStream output) output.WriteBytes(value); } } + if (groupList != null) + { + foreach (UnknownFieldSet value in groupList) + { + output.WriteTag(fieldNumber, WireFormat.WireType.StartGroup); + value.WriteTo(output); + output.WriteTag(fieldNumber, WireFormat.WireType.EndGroup); + } + } } /// @@ -168,6 +180,14 @@ internal int GetSerializedSize(int fieldNumber) result += CodedOutputStream.ComputeBytesSize(value); } } + if (groupList != null) + { + result += CodedOutputStream.ComputeTagSize(fieldNumber) * 2 * groupList.Count; + foreach (UnknownFieldSet value in groupList) + { + result += value.CalculateSize(); + } + } return result; } @@ -182,6 +202,7 @@ internal UnknownField MergeFrom(UnknownField other) fixed32List = AddAll(fixed32List, other.fixed32List); fixed64List = AddAll(fixed64List, other.fixed64List); lengthDelimitedList = AddAll(lengthDelimitedList, other.lengthDelimitedList); + groupList = AddAll(groupList, other.groupList); return this; } @@ -245,6 +266,12 @@ internal UnknownField AddLengthDelimited(ByteString value) return this; } + internal UnknownField AddGroup(UnknownFieldSet value) + { + groupList = Add(groupList, value); + return this; + } + /// /// Adds to the , creating /// a new list if is null. The list is returned - either diff --git a/csharp/src/Google.Protobuf/UnknownFieldSet.cs b/csharp/src/Google.Protobuf/UnknownFieldSet.cs index 6404c3c08f85..6a92fb9d97d9 100644 --- a/csharp/src/Google.Protobuf/UnknownFieldSet.cs +++ b/csharp/src/Google.Protobuf/UnknownFieldSet.cs @@ -215,7 +215,13 @@ private void MergeFieldFrom(CodedInputStream input) } case WireFormat.WireType.StartGroup: { - input.SkipGroup(tag); + uint endTag = WireFormat.MakeTag(number, WireFormat.WireType.EndGroup); + UnknownFieldSet set = new UnknownFieldSet(); + while (input.ReadTag() != endTag) + { + set.MergeFieldFrom(input); + } + GetOrAddField(number).AddGroup(set); return; } case WireFormat.WireType.EndGroup: From 9024b491521e77eeb32988f53c811c0fc68690fa Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Mon, 24 Sep 2018 20:41:00 -0500 Subject: [PATCH 02/11] Group compiler changes --- BUILD | 2 + src/Makefile.am | 4 + .../compiler/csharp/csharp_group_field.cc | 188 ++++++++++++++++++ .../compiler/csharp/csharp_group_field.h | 82 ++++++++ .../compiler/csharp/csharp_helpers.cc | 11 + .../csharp/csharp_repeated_group_field.cc | 86 ++++++++ .../csharp/csharp_repeated_group_field.h | 64 ++++++ 7 files changed, 437 insertions(+) create mode 100644 src/google/protobuf/compiler/csharp/csharp_group_field.cc create mode 100644 src/google/protobuf/compiler/csharp/csharp_group_field.h create mode 100644 src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc create mode 100644 src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h diff --git a/BUILD b/BUILD index 58d7a82bfd27..649451b35110 100644 --- a/BUILD +++ b/BUILD @@ -301,10 +301,12 @@ cc_library( "src/google/protobuf/compiler/csharp/csharp_map_field.cc", "src/google/protobuf/compiler/csharp/csharp_message.cc", "src/google/protobuf/compiler/csharp/csharp_message_field.cc", + "src/google/protobuf/compiler/csharp/csharp_group_field.cc", "src/google/protobuf/compiler/csharp/csharp_primitive_field.cc", "src/google/protobuf/compiler/csharp/csharp_reflection_class.cc", "src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc", "src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc", + "src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc", "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc", "src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc", "src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc", diff --git a/src/Makefile.am b/src/Makefile.am index 1aabf97207d0..49d4bc6b3f99 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -450,6 +450,8 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/csharp/csharp_message.h \ google/protobuf/compiler/csharp/csharp_message_field.cc \ google/protobuf/compiler/csharp/csharp_message_field.h \ + google/protobuf/compiler/csharp/csharp_group_field.cc \ + google/protobuf/compiler/csharp/csharp_group_field.h \ google/protobuf/compiler/csharp/csharp_options.h \ google/protobuf/compiler/csharp/csharp_primitive_field.cc \ google/protobuf/compiler/csharp/csharp_primitive_field.h \ @@ -459,6 +461,8 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/csharp/csharp_repeated_enum_field.h \ google/protobuf/compiler/csharp/csharp_repeated_message_field.cc \ google/protobuf/compiler/csharp/csharp_repeated_message_field.h \ + google/protobuf/compiler/csharp/csharp_repeated_group_field.cc \ + google/protobuf/compiler/csharp/csharp_repeated_group_field.h \ google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc \ google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h \ google/protobuf/compiler/csharp/csharp_source_generator_base.cc \ diff --git a/src/google/protobuf/compiler/csharp/csharp_group_field.cc b/src/google/protobuf/compiler/csharp/csharp_group_field.cc new file mode 100644 index 000000000000..c7ab7f5a56af --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_group_field.cc @@ -0,0 +1,188 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +GroupFieldGenerator::GroupFieldGenerator(const FieldDescriptor* descriptor, + int presenceIndex, + const Options *options) + : MessageFieldGenerator(descriptor, presenceIndex, options) { + int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()) / 2; + uint tag = internal::WireFormatLite::MakeTag( + descriptor_->number(), + internal::WireFormatLite::WIRETYPE_END_GROUP); + 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_["end_tag"] = SimpleItoa(tag); + variables_["end_tag_bytes"] = tag_bytes; +} + +GroupFieldGenerator::~GroupFieldGenerator() { + +} + +void GroupFieldGenerator::GenerateParsingCode(io::Printer* printer) { + printer->Print( + variables_, + "if ($has_not_property_check$) {\n" + " $name$_ = new $type_name$();\n" + "}\n" + "input.ReadGroup($name$_);\n"); +} + +void GroupFieldGenerator::GenerateSerializationCode(io::Printer* printer) { + printer->Print( + variables_, + "if ($has_property_check$) {\n" + " output.WriteRawTag($tag_bytes$);\n" + " output.WriteGroup($property_name$);\n" + " output.WriteRawTag($end_tag_bytes$);\n" + "}\n"); +} + +void GroupFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { + printer->Print( + variables_, + "if ($has_property_check$) {\n" + " size += $tag_size$ + $tag_size$ + pb::CodedOutputStream.ComputeGroupSize($property_name$);\n" + "}\n"); +} + +void GroupFieldGenerator::GenerateCodecCode(io::Printer* printer) { + printer->Print( + variables_, + "pb::FieldCodec.ForGroup($tag$, $end_tag$, $type_name$.Parser)"); +} + +GroupOneofFieldGenerator::GroupOneofFieldGenerator( + const FieldDescriptor* descriptor, + int presenceIndex, + const Options *options) + : GroupFieldGenerator(descriptor, presenceIndex, options) { + SetCommonOneofFieldVariables(&variables_); +} + +GroupOneofFieldGenerator::~GroupOneofFieldGenerator() { + +} + +void GroupOneofFieldGenerator::GenerateMembers(io::Printer* printer) { + WritePropertyDocComment(printer, descriptor_); + AddPublicMemberAttributes(printer); + printer->Print( + variables_, + "$access_level$ $type_name$ $property_name$ {\n" + " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n" + " set {\n" + " $oneof_name$_ = value;\n" + " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" + " }\n" + "}\n"); + printer->Print( + variables_, + "/// Gets whether the \"$descriptor_name$\" field is set\n"); + AddPublicMemberAttributes(printer); + printer->Print( + variables_, + "$access_level$ bool Has$property_name$ {\n" + " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n" + "}\n"); + printer->Print( + variables_, + "/// Clears the value of the oneof if it's currently set to \"$descriptor_name$\" \n"); + AddPublicMemberAttributes(printer); + printer->Print( + variables_, + "$access_level$ void Clear$property_name$() {\n" + " if ($has_property_check$) {\n" + " Clear$oneof_property_name$();\n" + " }\n" + "}\n"); +} + +void GroupOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { + printer->Print(variables_, + "if ($property_name$ == null) {\n" + " $property_name$ = new $type_name$();\n" + "}\n" + "$property_name$.MergeFrom(other.$property_name$);\n"); +} + +void GroupOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { + // TODO(jonskeet): We may be able to do better than this + printer->Print( + variables_, + "$type_name$ subBuilder = new $type_name$();\n" + "if ($has_property_check$) {\n" + " subBuilder.MergeFrom($property_name$);\n" + "}\n" + "input.ReadGroup(subBuilder);\n" + "$property_name$ = subBuilder;\n"); +} + +void GroupOneofFieldGenerator::WriteToString(io::Printer* printer) { + printer->Print( + variables_, + "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n"); +} + +void GroupOneofFieldGenerator::GenerateCloningCode(io::Printer* printer) { + printer->Print(variables_, + "$property_name$ = other.$property_name$.Clone();\n"); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_group_field.h b/src/google/protobuf/compiler/csharp/csharp_group_field.h new file mode 100644 index 000000000000..3aa1fdf05800 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_group_field.h @@ -0,0 +1,82 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GROUP_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GROUP_FIELD_H__ + +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class GroupFieldGenerator : public MessageFieldGenerator { + public: + GroupFieldGenerator(const FieldDescriptor* descriptor, + int presenceIndex, + const Options *options); + ~GroupFieldGenerator(); + + virtual void GenerateCodecCode(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer); + virtual void GenerateSerializationCode(io::Printer* printer); + virtual void GenerateSerializedSizeCode(io::Printer* printer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GroupFieldGenerator); +}; + +class GroupOneofFieldGenerator : public GroupFieldGenerator { + public: + GroupOneofFieldGenerator(const FieldDescriptor* descriptor, + int presenceIndex, + const Options *options); + ~GroupOneofFieldGenerator(); + + virtual void GenerateCloningCode(io::Printer* printer); + virtual void GenerateMembers(io::Printer* printer); + virtual void GenerateMergingCode(io::Printer* printer); + virtual void WriteToString(io::Printer* printer); + virtual void GenerateParsingCode(io::Printer* printer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GroupOneofFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GROUP_FIELD_H__ \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index dace41006aea..bb0ea1d42f39 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -50,10 +50,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -457,6 +459,15 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, const Options* options) { switch (descriptor->type()) { case FieldDescriptor::TYPE_GROUP: + if (descriptor->is_repeated()) { + return new RepeatedGroupFieldGenerator(descriptor, presenceIndex, options); + } else { + if (descriptor->containing_oneof()) { + return new GroupOneofFieldGenerator(descriptor, presenceIndex, options); + } else { + return new GroupFieldGenerator(descriptor, presenceIndex, options); + } + } case FieldDescriptor::TYPE_MESSAGE: if (descriptor->is_repeated()) { if (descriptor->is_map()) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc new file mode 100644 index 000000000000..e47427b58e81 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc @@ -0,0 +1,86 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +RepeatedGroupFieldGenerator::RepeatedGroupFieldGenerator( + const FieldDescriptor* descriptor, int presenceIndex, const Options *options) + : RepeatedMessageFieldGenerator(descriptor, presenceIndex, options) { +} + +RepeatedGroupFieldGenerator::~RepeatedGroupFieldGenerator() { + +} + +void RepeatedGroupFieldGenerator::GenerateMembers(io::Printer* printer) { + printer->Print( + variables_, + "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" + " = "); + // Don't want to duplicate the codec code here... maybe we should have a + // "create single field generator for this repeated field" + // function, but it doesn't seem worth it for just this. + std::unique_ptr single_generator( + new GroupFieldGenerator(descriptor_, presenceIndex_, this->options())); + single_generator->GenerateCodecCode(printer); + printer->Print(";\n"); + printer->Print( + variables_, + "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); + WritePropertyDocComment(printer, descriptor_); + AddPublicMemberAttributes(printer); + printer->Print( + variables_, + "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n" + " get { return $name$_; }\n" + "}\n"); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h new file mode 100644 index 000000000000..f183a79dca4c --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h @@ -0,0 +1,64 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_GROUP_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_GROUP_FIELD_H__ + +#include + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +struct Options; + +class RepeatedGroupFieldGenerator : public RepeatedMessageFieldGenerator { + public: + RepeatedGroupFieldGenerator(const FieldDescriptor* descriptor, + int presenceIndex, + const Options *options); + ~RepeatedGroupFieldGenerator(); + + virtual void GenerateMembers(io::Printer* printer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedGroupFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_GROUP_FIELD_H__ \ No newline at end of file From 9c079c597ee61f65cb465e4e340dc2d2dd22dfd0 Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Mon, 24 Sep 2018 21:45:36 -0500 Subject: [PATCH 03/11] Fixed a typo in FieldCodec which resulted in some failed tests --- csharp/src/Google.Protobuf/FieldCodec.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs index 0d0983869f7c..221ad5fd2d50 100644 --- a/csharp/src/Google.Protobuf/FieldCodec.cs +++ b/csharp/src/Google.Protobuf/FieldCodec.cs @@ -436,7 +436,7 @@ static FieldCodec() Func reader, Action writer, int fixedSize, - uint tag) : this(reader, writer, _ => fixedSize, 0, tag) + uint tag) : this(reader, writer, _ => fixedSize, tag) { FixedSize = fixedSize; } From 8a43b56c5271b480da2f88d4eef8482c6d8dc346 Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Mon, 24 Sep 2018 22:30:12 -0500 Subject: [PATCH 04/11] Added new group files to cmake build files --- cmake/libprotoc.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 850a85a67534..0a956f0d401d 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -24,10 +24,12 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_map_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_group_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc From 1048bf0976675d47e856069810e1013ae1baee1a Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Thu, 25 Oct 2018 13:54:11 -0500 Subject: [PATCH 05/11] Insert ReachedTagLimit check on ReadTag to return 0 on last tag --- csharp/src/Google.Protobuf/CodedInputStream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs index 6e6406f0cda6..1216b2005cdf 100644 --- a/csharp/src/Google.Protobuf/CodedInputStream.cs +++ b/csharp/src/Google.Protobuf/CodedInputStream.cs @@ -384,7 +384,7 @@ public uint ReadTag() // If we actually read a tag with a field of 0, that's not a valid tag. throw InvalidProtocolBufferException.InvalidTag(); } - if (ReachedLimit) + if (ReachedLimit || ReachedTagLimit) { return 0; } From f7f732df94372d7323ef3e4ca6cedccea5593e8a Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Mon, 29 Oct 2018 19:43:17 -0500 Subject: [PATCH 06/11] Compiler changes (end tag review) --- src/Makefile.am | 4 - .../compiler/csharp/csharp_group_field.cc | 188 ------------------ .../compiler/csharp/csharp_group_field.h | 82 -------- .../compiler/csharp/csharp_helpers.cc | 11 - .../compiler/csharp/csharp_message.cc | 4 +- .../compiler/csharp/csharp_message_field.cc | 104 +++++++--- .../csharp/csharp_repeated_group_field.cc | 86 -------- .../csharp/csharp_repeated_group_field.h | 64 ------ 8 files changed, 83 insertions(+), 460 deletions(-) delete mode 100644 src/google/protobuf/compiler/csharp/csharp_group_field.cc delete mode 100644 src/google/protobuf/compiler/csharp/csharp_group_field.h delete mode 100644 src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc delete mode 100644 src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h diff --git a/src/Makefile.am b/src/Makefile.am index 49d4bc6b3f99..1aabf97207d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -450,8 +450,6 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/csharp/csharp_message.h \ google/protobuf/compiler/csharp/csharp_message_field.cc \ google/protobuf/compiler/csharp/csharp_message_field.h \ - google/protobuf/compiler/csharp/csharp_group_field.cc \ - google/protobuf/compiler/csharp/csharp_group_field.h \ google/protobuf/compiler/csharp/csharp_options.h \ google/protobuf/compiler/csharp/csharp_primitive_field.cc \ google/protobuf/compiler/csharp/csharp_primitive_field.h \ @@ -461,8 +459,6 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/csharp/csharp_repeated_enum_field.h \ google/protobuf/compiler/csharp/csharp_repeated_message_field.cc \ google/protobuf/compiler/csharp/csharp_repeated_message_field.h \ - google/protobuf/compiler/csharp/csharp_repeated_group_field.cc \ - google/protobuf/compiler/csharp/csharp_repeated_group_field.h \ google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc \ google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h \ google/protobuf/compiler/csharp/csharp_source_generator_base.cc \ diff --git a/src/google/protobuf/compiler/csharp/csharp_group_field.cc b/src/google/protobuf/compiler/csharp/csharp_group_field.cc deleted file mode 100644 index c7ab7f5a56af..000000000000 --- a/src/google/protobuf/compiler/csharp/csharp_group_field.cc +++ /dev/null @@ -1,188 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -GroupFieldGenerator::GroupFieldGenerator(const FieldDescriptor* descriptor, - int presenceIndex, - const Options *options) - : MessageFieldGenerator(descriptor, presenceIndex, options) { - int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()) / 2; - uint tag = internal::WireFormatLite::MakeTag( - descriptor_->number(), - internal::WireFormatLite::WIRETYPE_END_GROUP); - 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_["end_tag"] = SimpleItoa(tag); - variables_["end_tag_bytes"] = tag_bytes; -} - -GroupFieldGenerator::~GroupFieldGenerator() { - -} - -void GroupFieldGenerator::GenerateParsingCode(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_not_property_check$) {\n" - " $name$_ = new $type_name$();\n" - "}\n" - "input.ReadGroup($name$_);\n"); -} - -void GroupFieldGenerator::GenerateSerializationCode(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) {\n" - " output.WriteRawTag($tag_bytes$);\n" - " output.WriteGroup($property_name$);\n" - " output.WriteRawTag($end_tag_bytes$);\n" - "}\n"); -} - -void GroupFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) {\n" - " size += $tag_size$ + $tag_size$ + pb::CodedOutputStream.ComputeGroupSize($property_name$);\n" - "}\n"); -} - -void GroupFieldGenerator::GenerateCodecCode(io::Printer* printer) { - printer->Print( - variables_, - "pb::FieldCodec.ForGroup($tag$, $end_tag$, $type_name$.Parser)"); -} - -GroupOneofFieldGenerator::GroupOneofFieldGenerator( - const FieldDescriptor* descriptor, - int presenceIndex, - const Options *options) - : GroupFieldGenerator(descriptor, presenceIndex, options) { - SetCommonOneofFieldVariables(&variables_); -} - -GroupOneofFieldGenerator::~GroupOneofFieldGenerator() { - -} - -void GroupOneofFieldGenerator::GenerateMembers(io::Printer* printer) { - WritePropertyDocComment(printer, descriptor_); - AddPublicMemberAttributes(printer); - printer->Print( - variables_, - "$access_level$ $type_name$ $property_name$ {\n" - " get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n" - " set {\n" - " $oneof_name$_ = value;\n" - " $oneof_name$Case_ = value == null ? $oneof_property_name$OneofCase.None : $oneof_property_name$OneofCase.$property_name$;\n" - " }\n" - "}\n"); - printer->Print( - variables_, - "/// Gets whether the \"$descriptor_name$\" field is set\n"); - AddPublicMemberAttributes(printer); - printer->Print( - variables_, - "$access_level$ bool Has$property_name$ {\n" - " get { return $oneof_name$Case_ == $oneof_property_name$OneofCase.$property_name$; }\n" - "}\n"); - printer->Print( - variables_, - "/// Clears the value of the oneof if it's currently set to \"$descriptor_name$\" \n"); - AddPublicMemberAttributes(printer); - printer->Print( - variables_, - "$access_level$ void Clear$property_name$() {\n" - " if ($has_property_check$) {\n" - " Clear$oneof_property_name$();\n" - " }\n" - "}\n"); -} - -void GroupOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { - printer->Print(variables_, - "if ($property_name$ == null) {\n" - " $property_name$ = new $type_name$();\n" - "}\n" - "$property_name$.MergeFrom(other.$property_name$);\n"); -} - -void GroupOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { - // TODO(jonskeet): We may be able to do better than this - printer->Print( - variables_, - "$type_name$ subBuilder = new $type_name$();\n" - "if ($has_property_check$) {\n" - " subBuilder.MergeFrom($property_name$);\n" - "}\n" - "input.ReadGroup(subBuilder);\n" - "$property_name$ = subBuilder;\n"); -} - -void GroupOneofFieldGenerator::WriteToString(io::Printer* printer) { - printer->Print( - variables_, - "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n"); -} - -void GroupOneofFieldGenerator::GenerateCloningCode(io::Printer* printer) { - printer->Print(variables_, - "$property_name$ = other.$property_name$.Clone();\n"); -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_group_field.h b/src/google/protobuf/compiler/csharp/csharp_group_field.h deleted file mode 100644 index 3aa1fdf05800..000000000000 --- a/src/google/protobuf/compiler/csharp/csharp_group_field.h +++ /dev/null @@ -1,82 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GROUP_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GROUP_FIELD_H__ - -#include - -#include -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -class GroupFieldGenerator : public MessageFieldGenerator { - public: - GroupFieldGenerator(const FieldDescriptor* descriptor, - int presenceIndex, - const Options *options); - ~GroupFieldGenerator(); - - virtual void GenerateCodecCode(io::Printer* printer); - virtual void GenerateParsingCode(io::Printer* printer); - virtual void GenerateSerializationCode(io::Printer* printer); - virtual void GenerateSerializedSizeCode(io::Printer* printer); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GroupFieldGenerator); -}; - -class GroupOneofFieldGenerator : public GroupFieldGenerator { - public: - GroupOneofFieldGenerator(const FieldDescriptor* descriptor, - int presenceIndex, - const Options *options); - ~GroupOneofFieldGenerator(); - - virtual void GenerateCloningCode(io::Printer* printer); - virtual void GenerateMembers(io::Printer* printer); - virtual void GenerateMergingCode(io::Printer* printer); - virtual void WriteToString(io::Printer* printer); - virtual void GenerateParsingCode(io::Printer* printer); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GroupOneofFieldGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GROUP_FIELD_H__ \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index bb0ea1d42f39..dace41006aea 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -50,12 +50,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include @@ -459,15 +457,6 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, const Options* options) { switch (descriptor->type()) { case FieldDescriptor::TYPE_GROUP: - if (descriptor->is_repeated()) { - return new RepeatedGroupFieldGenerator(descriptor, presenceIndex, options); - } else { - if (descriptor->containing_oneof()) { - return new GroupOneofFieldGenerator(descriptor, presenceIndex, options); - } else { - return new GroupFieldGenerator(descriptor, presenceIndex, options); - } - } case FieldDescriptor::TYPE_MESSAGE: if (descriptor->is_repeated()) { if (descriptor->is_map()) { diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index 1daae6f595ea..cf694d6074d7 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -531,7 +531,9 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { } else { printer->Print( "default:\n" - " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n" + " if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) {\n" + " return;\n" + " }\n" " break;\n"); } for (int i = 0; i < fields_by_number().size(); i++) { diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index 16714603671f..3db69dd546a2 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include #include @@ -56,6 +58,21 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, variables_["has_property_check"] = name() + "_ != null"; variables_["has_not_property_check"] = name() + "_ == null"; } + + if (descriptor_->type() == FieldDescriptor::Type::TYPE_GROUP) { + int tag_size = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()) / 2; + uint tag = internal::WireFormatLite::MakeTag( + descriptor_->number(), + internal::WireFormatLite::WIRETYPE_END_GROUP); + 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_["end_tag"] = SimpleItoa(tag); + variables_["end_tag_bytes"] = tag_bytes; + } } MessageFieldGenerator::~MessageFieldGenerator() { @@ -114,25 +131,47 @@ void MessageFieldGenerator::GenerateParsingCode(io::Printer* printer) { variables_, "if ($has_not_property_check$) {\n" " $property_name$ = new $type_name$();\n" - "}\n" - "input.ReadMessage($property_name$);\n"); + "}\n"); + if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) { + printer->Print(variables_, "input.ReadMessage($property_name$);\n"); + } else { + printer->Print(variables_, "input.ReadGroup($property_name$);\n"); + } } void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) {\n" - " output.WriteRawTag($tag_bytes$);\n" - " output.WriteMessage($property_name$);\n" - "}\n"); + if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) { + printer->Print( + variables_, + "if ($has_property_check$) {\n" + " output.WriteRawTag($tag_bytes$);\n" + " output.WriteMessage($property_name$);\n" + "}\n"); + } else { + printer->Print( + variables_, + "if ($has_property_check$) {\n" + " output.WriteRawTag($tag_bytes$);\n" + " output.WriteGroup($property_name$);\n" + " output.WriteRawTag($end_tag_bytes$);\n" + "}\n"); + } } void MessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) {\n" - " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($property_name$);\n" - "}\n"); + if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) { + printer->Print( + variables_, + "if ($has_property_check$) {\n" + " size += $tag_size$ + pb::CodedOutputStream.ComputeMessageSize($property_name$);\n" + "}\n"); + } else { + printer->Print( + variables_, + "if ($has_property_check$) {\n" + " size += $tag_size$ + $tag_size$ + pb::CodedOutputStream.ComputeGroupSize($property_name$);\n" + "}\n"); + } } void MessageFieldGenerator::WriteHash(io::Printer* printer) { @@ -160,9 +199,15 @@ void MessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) { } void MessageFieldGenerator::GenerateCodecCode(io::Printer* printer) { - printer->Print( - variables_, - "pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)"); + if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) { + printer->Print( + variables_, + "pb::FieldCodec.ForMessage($tag$, $type_name$.Parser)"); + } else { + printer->Print( + variables_, + "pb::FieldCodec.ForGroup($tag$, $end_tag$, $type_name$.Parser)"); + } } MessageOneofFieldGenerator::MessageOneofFieldGenerator( @@ -223,14 +268,25 @@ void MessageOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { // TODO(jonskeet): We may be able to do better than this - printer->Print( - variables_, - "$type_name$ subBuilder = new $type_name$();\n" - "if ($has_property_check$) {\n" - " subBuilder.MergeFrom($property_name$);\n" - "}\n" - "input.ReadMessage(subBuilder);\n" - "$property_name$ = subBuilder;\n"); + if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) { + printer->Print( + variables_, + "$type_name$ subBuilder = new $type_name$();\n" + "if ($has_property_check$) {\n" + " subBuilder.MergeFrom($property_name$);\n" + "}\n" + "input.ReadMessage(subBuilder);\n" + "$property_name$ = subBuilder;\n"); + } else { + printer->Print( + variables_, + "$type_name$ subBuilder = new $type_name$();\n" + "if ($has_property_check$) {\n" + " subBuilder.MergeFrom($property_name$);\n" + "}\n" + "input.ReadGroup(subBuilder);\n" + "$property_name$ = subBuilder;\n"); + } } void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc deleted file mode 100644 index e47427b58e81..000000000000 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -RepeatedGroupFieldGenerator::RepeatedGroupFieldGenerator( - const FieldDescriptor* descriptor, int presenceIndex, const Options *options) - : RepeatedMessageFieldGenerator(descriptor, presenceIndex, options) { -} - -RepeatedGroupFieldGenerator::~RepeatedGroupFieldGenerator() { - -} - -void RepeatedGroupFieldGenerator::GenerateMembers(io::Printer* printer) { - printer->Print( - variables_, - "private static readonly pb::FieldCodec<$type_name$> _repeated_$name$_codec\n" - " = "); - // Don't want to duplicate the codec code here... maybe we should have a - // "create single field generator for this repeated field" - // function, but it doesn't seem worth it for just this. - std::unique_ptr single_generator( - new GroupFieldGenerator(descriptor_, presenceIndex_, this->options())); - single_generator->GenerateCodecCode(printer); - printer->Print(";\n"); - printer->Print( - variables_, - "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n"); - WritePropertyDocComment(printer, descriptor_); - AddPublicMemberAttributes(printer); - printer->Print( - variables_, - "$access_level$ pbc::RepeatedField<$type_name$> $property_name$ {\n" - " get { return $name$_; }\n" - "}\n"); -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google \ No newline at end of file diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h deleted file mode 100644 index f183a79dca4c..000000000000 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.h +++ /dev/null @@ -1,64 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_GROUP_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_GROUP_FIELD_H__ - -#include - -#include -#include - -namespace google { -namespace protobuf { -namespace compiler { -namespace csharp { - -struct Options; - -class RepeatedGroupFieldGenerator : public RepeatedMessageFieldGenerator { - public: - RepeatedGroupFieldGenerator(const FieldDescriptor* descriptor, - int presenceIndex, - const Options *options); - ~RepeatedGroupFieldGenerator(); - - virtual void GenerateMembers(io::Printer* printer); - - private: - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedGroupFieldGenerator); -}; - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_GROUP_FIELD_H__ \ No newline at end of file From 7b7b436eca36736aa1c8aefb3d61812d0707f2b8 Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Mon, 29 Oct 2018 19:44:09 -0500 Subject: [PATCH 07/11] Generated code changes (end tag review) --- csharp/src/AddressBook/Addressbook.cs | 12 +- .../Conformance.cs | 8 +- .../TestProtos/MapUnittestProto3.cs | 28 +++- .../TestProtos/TestMessagesProto3.cs | 12 +- .../TestProtos/UnittestCustomOptionsProto3.cs | 84 +++++++--- .../TestProtos/UnittestImportProto3.cs | 4 +- .../TestProtos/UnittestImportPublicProto3.cs | 4 +- .../TestProtos/UnittestIssues.cs | 52 ++++-- .../TestProtos/UnittestProto3.cs | 156 +++++++++++++----- .../TestProtos/UnittestWellKnownTypes.cs | 16 +- csharp/src/Google.Protobuf.Test/testprotos.pb | Bin 204268 -> 204331 bytes .../Google.Protobuf/Reflection/Descriptor.cs | 76 ++++++--- .../src/Google.Protobuf/WellKnownTypes/Any.cs | 4 +- .../src/Google.Protobuf/WellKnownTypes/Api.cs | 12 +- .../WellKnownTypes/Duration.cs | 4 +- .../Google.Protobuf/WellKnownTypes/Empty.cs | 4 +- .../WellKnownTypes/FieldMask.cs | 4 +- .../WellKnownTypes/SourceContext.cs | 4 +- .../Google.Protobuf/WellKnownTypes/Struct.cs | 12 +- .../WellKnownTypes/Timestamp.cs | 4 +- .../Google.Protobuf/WellKnownTypes/Type.cs | 20 ++- .../WellKnownTypes/Wrappers.cs | 36 +++- 22 files changed, 417 insertions(+), 139 deletions(-) diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs index d3e1ea95344f..c05125c629cd 100644 --- a/csharp/src/AddressBook/Addressbook.cs +++ b/csharp/src/AddressBook/Addressbook.cs @@ -260,7 +260,9 @@ public sealed partial class Person : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -440,7 +442,9 @@ public sealed partial class PhoneNumber : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Number = input.ReadString(); @@ -573,7 +577,9 @@ public sealed partial class AddressBook : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { people_.AddEntriesFrom(input, _repeated_people_codec); diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs index cd9b77abe5fc..1642669e92ca 100644 --- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs +++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs @@ -343,7 +343,9 @@ public enum PayloadOneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { ProtobufPayload = input.ReadBytes(); @@ -683,7 +685,9 @@ public enum ResultOneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { ParseError = input.ReadString(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs index 6d3cd026d112..2844ca62ce4e 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs @@ -541,7 +541,9 @@ public sealed partial class TestMap : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec); @@ -737,7 +739,9 @@ public sealed partial class TestMapSubmessage : pb::IMessage while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { if (testMap_ == null) { @@ -861,7 +865,9 @@ public sealed partial class TestMessageMap : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { mapInt32Message_.AddEntriesFrom(input, _map_mapInt32Message_codec); @@ -1001,7 +1007,9 @@ public sealed partial class TestSameTypeMap : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { map1_.AddEntriesFrom(input, _map_map1_codec); @@ -1350,7 +1358,9 @@ public sealed partial class TestArenaMap : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { mapInt32Int32_.AddEntriesFrom(input, _map_mapInt32Int32_codec); @@ -1531,7 +1541,9 @@ public sealed partial class MessageContainingEnumCalledType : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { A = input.ReadInt32(); @@ -3723,7 +3727,9 @@ public sealed partial class ForeignMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { C = input.ReadInt32(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs index 2a9efe55fff1..9b9ffe256005 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs @@ -352,7 +352,9 @@ public enum AnOneofOneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Field1 = input.ReadString(); @@ -478,7 +480,9 @@ public sealed partial class CustomOptionFooRequest : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { I = input.ReadInt32(); @@ -2615,7 +2651,9 @@ public sealed partial class AggregateMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Fieldname = input.ReadInt32(); @@ -2723,7 +2761,9 @@ public sealed partial class NestedOptionType : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -2855,7 +2895,9 @@ public sealed partial class NestedMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { NestedField = input.ReadInt32(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs index 6bf97151715e..931dc2eb03a0 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs @@ -167,7 +167,9 @@ public sealed partial class ImportMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { D = input.ReadInt32(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs index 97d181aff48c..fee0120b42d1 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs @@ -155,7 +155,9 @@ public sealed partial class PublicImportMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -284,7 +286,9 @@ public sealed partial class NestedOnce : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -387,7 +391,9 @@ public sealed partial class NestedTwice : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -554,7 +560,9 @@ public sealed partial class NegativeEnumMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -899,7 +909,9 @@ public sealed partial class DeprecatedFieldsMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Item = input.ReadInt32(); @@ -1209,7 +1223,9 @@ public sealed partial class ReservedNames : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Types_ = input.ReadInt32(); @@ -1323,7 +1339,9 @@ public sealed partial class SomeNestedType : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -1647,7 +1665,9 @@ public enum O2OneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { PlainString = input.ReadString(); @@ -1847,7 +1867,9 @@ public sealed partial class TestJsonName : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -2047,7 +2069,9 @@ public enum ValueOneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Text = input.ReadString(); @@ -2211,7 +2235,9 @@ public sealed partial class Nested : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { X = input.ReadInt32(); diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs index bbbee22c7b6a..1d4367b78151 100644 --- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs +++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs @@ -1387,7 +1387,9 @@ public enum OneofFieldOneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { SingleInt32 = input.ReadInt32(); @@ -1755,7 +1757,9 @@ public sealed partial class NestedMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Bb = input.ReadInt32(); @@ -1938,7 +1942,9 @@ public sealed partial class NestedTestAllTypes : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { C = input.ReadInt32(); @@ -2320,7 +2330,9 @@ public sealed partial class TestReservedFields : pb::IMessage while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { if (foreignNested_ == null) { @@ -2614,7 +2628,9 @@ public sealed partial class TestReallyLargeTagNumber : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Bb = input.ReadInt32(); @@ -4037,7 +4067,9 @@ public sealed partial class SparseEnumMessage : pb::IMessage while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { SparseEnum = (global::Google.Protobuf.TestProtos.TestSparseEnum) input.ReadEnum(); @@ -4169,7 +4201,9 @@ public sealed partial class OneString : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Data = input.ReadString(); @@ -4290,7 +4324,9 @@ public sealed partial class MoreString : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { data_.AddEntriesFrom(input, _repeated_data_codec); @@ -4419,7 +4455,9 @@ public sealed partial class OneBytes : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Data = input.ReadBytes(); @@ -4548,7 +4586,9 @@ public sealed partial class MoreBytes : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Data = input.ReadBytes(); @@ -4680,7 +4720,9 @@ public sealed partial class Int32Message : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Data = input.ReadInt32(); @@ -4809,7 +4851,9 @@ public sealed partial class Uint32Message : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Data = input.ReadUInt32(); @@ -4938,7 +4982,9 @@ public sealed partial class Int64Message : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Data = input.ReadInt64(); @@ -5067,7 +5113,9 @@ public sealed partial class Uint64Message : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Data = input.ReadUInt64(); @@ -5196,7 +5244,9 @@ public sealed partial class BoolMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Data = input.ReadBool(); @@ -5413,7 +5463,9 @@ public enum FooOneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { FooInt = input.ReadInt32(); @@ -5755,7 +5807,9 @@ public sealed partial class TestPackedTypes : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 722: case 720: { @@ -6154,7 +6208,9 @@ public sealed partial class TestUnpackedTypes : pb::IMessage while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 722: case 720: { @@ -6435,7 +6491,9 @@ public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -6802,7 +6864,9 @@ public sealed partial class FooResponse : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -6903,7 +6967,9 @@ public sealed partial class FooClientMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -7004,7 +7070,9 @@ public sealed partial class FooServerMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -7105,7 +7173,9 @@ public sealed partial class BarRequest : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -7206,7 +7276,9 @@ public sealed partial class BarResponse : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -7307,7 +7379,9 @@ public sealed partial class TestEmptyMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } @@ -7438,7 +7512,9 @@ public sealed partial class CommentMessage : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Text = input.ReadString(); @@ -7585,7 +7661,9 @@ public sealed partial class NestedCommentMessage : pb::IMessage while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { anyField_.AddEntriesFrom(input, _map_anyField_codec); diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index 94ff381705adf502343e9f07e16d4719499e81dd..69950675d86e0a5652389de1849e7fcdbcef85e1 100644 GIT binary patch delta 633 zcmZvYO>0v@6oxaWH*FkKqqmA+B^)Y(#U%Ye{KAcv`h_4!U6n4zd&gwz%}ks-u||Sz zKuCXpG8>i6AtTF8)3Ok%>H<8yU#mh! z1-fV3Hz}N$s$e@6vW^Uw=g(9ds_hOVq{F&c(|s$a?9MhRqY+I$Gjyi?Fn<@#WS#rF z+}EmUzou|Lz$+bU%LXo$+=1d@0hjMwU7+^#6Q~wrW;musyMgIo+W^^ruv<7pUlAGv zImm@UkJvBk@cjA#n)gN!=6eLX6Lfr6=Y0akGD*BFlrlNuWjH~<@8VpwZ{Kae=ZmFb iHwnVgK7k%Nyw^Y+&KVhw_y$rK&#DgBAAIZqzWfK^rLeF7 delta 582 zcmZXPL2DC16vua7c1@h7Mz;#ZqC8Y6g&GS1q3FpNi#Mry@*v~xm`uBwNoOXs*-L`j zB3@PI(obNI3Q_dv-A~}rn}`QLfU`{kg17nce((Q(bM&S9^K*6df_#8WTc!8csC)Sq z(6zSU+sRK?X*rHA1_$F`V=_45els}dj&^|6J}yxRgE-2A147Qfb4wap7bq%?3Cp-l znO;TBdzu?AEl-gd_e#T!Aqt5PA2hMmQ%MJ{=<+(=wI~d7nW)s8eIsNWZHH65r&Y## zRwTHgd0T10BsQnoSNFVG*8Boc@F?#~Fm lub(fiJogOn@Gtd%ox=bC diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index 0c33e63df46a..f101cd35265c 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -302,7 +302,9 @@ internal sealed partial class FileDescriptorSet : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -1357,7 +1363,9 @@ internal sealed partial class ExtensionRange : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Start = input.ReadInt32(); @@ -1560,7 +1568,9 @@ internal sealed partial class ReservedRange : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Start = input.ReadInt32(); @@ -1693,7 +1703,9 @@ internal sealed partial class ExtensionRangeOptions : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { NamePart_ = input.ReadString(); @@ -7315,7 +7345,9 @@ internal sealed partial class SourceCodeInfo : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { location_.AddEntriesFrom(input, _repeated_location_codec); @@ -7623,7 +7655,9 @@ internal sealed partial class Location : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: case 8: { @@ -7776,7 +7810,9 @@ internal sealed partial class GeneratedCodeInfo : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: case 8: { diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs index dd9911067ed9..b1ed0bc3077c 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs @@ -292,7 +292,9 @@ public sealed partial class Any : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { TypeUrl = input.ReadString(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs index 438e1db8da2f..a566e406403b 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs @@ -345,7 +345,9 @@ public sealed partial class Api : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -661,7 +663,9 @@ public sealed partial class Method : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -925,7 +929,9 @@ public sealed partial class Mixin : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs index 2858b532b636..691ca334ea2b 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs @@ -254,7 +254,9 @@ public sealed partial class Duration : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Seconds = input.ReadInt64(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs index 2113add9bca1..03ffc4a05776 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs @@ -143,7 +143,9 @@ public sealed partial class Empty : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; } } diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs index 6ad31a50eacc..8114aa3924ef 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs @@ -352,7 +352,9 @@ public sealed partial class FieldMask : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { paths_.AddEntriesFrom(input, _repeated_paths_codec); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs index 124ddaa71234..2cae68631df8 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs @@ -165,7 +165,9 @@ public sealed partial class SourceContext : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { FileName = input.ReadString(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs index 194b81e965e5..9667472522e2 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs @@ -189,7 +189,9 @@ public sealed partial class Struct : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { fields_.AddEntriesFrom(input, _map_fields_codec); @@ -513,7 +515,9 @@ public enum KindOneofCase { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { kind_ = input.ReadEnum(); @@ -673,7 +677,9 @@ public sealed partial class ListValue : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { values_.AddEntriesFrom(input, _repeated_values_codec); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs index 984e226fd449..9e37e9dda7de 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs @@ -273,7 +273,9 @@ public sealed partial class Timestamp : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Seconds = input.ReadInt64(); diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs index 52bd343ba841..adea91063496 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs @@ -328,7 +328,9 @@ public sealed partial class Type : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -723,7 +725,9 @@ public sealed partial class Field : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 8: { Kind = (global::Google.Protobuf.WellKnownTypes.Field.Types.Kind) input.ReadEnum(); @@ -1100,7 +1104,9 @@ public sealed partial class Enum : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -1300,7 +1306,9 @@ public sealed partial class EnumValue : pb::IMessage { while ((tag = input.ReadTag()) != 0) { switch(tag) { default: - _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + if (!pb::UnknownFieldSet.MergeFieldFrom(ref _unknownFields, input)) { + return; + } break; case 10: { Name = input.ReadString(); @@ -1480,7 +1488,9 @@ public sealed partial class Option : pb::IMessage private int currentLimit = int.MaxValue; - private uint tagLimit = uint.MaxValue; private int recursionDepth = 0; @@ -384,7 +383,7 @@ public uint ReadTag() // If we actually read a tag with a field of 0, that's not a valid tag. throw InvalidProtocolBufferException.InvalidTag(); } - if (ReachedLimit || ReachedTagLimit) + if (ReachedLimit) { return 0; } @@ -605,15 +604,9 @@ public void ReadGroup(IMessage builder) { throw InvalidProtocolBufferException.RecursionLimitExceeded(); } - uint oldTag = PushTag(); ++recursionDepth; builder.MergeFrom(this); - if (!ReachedTagLimit) - { - throw InvalidProtocolBufferException.TruncatedMessage(); - } --recursionDepth; - PopTag(oldTag); } /// @@ -978,19 +971,6 @@ internal int PushLimit(int byteLimit) return oldLimit; } - /// - /// Sets tagLimit to the limit calculated by the last tag. - /// This is called when descending into a group message. The previous limit is returns. - /// - /// The old limit - internal uint PushTag() - { - uint oldLimit = tagLimit; - uint newLimit = WireFormat.MakeTag(WireFormat.GetTagFieldNumber(LastTag), WireFormat.WireType.EndGroup); - tagLimit = newLimit; - return oldLimit; - } - private void RecomputeBufferSizeAfterLimit() { bufferSize += bufferSizeAfterLimit; @@ -1016,14 +996,6 @@ internal void PopLimit(int oldLimit) RecomputeBufferSizeAfterLimit(); } - /// - /// Discards the current limit, returning the previous limit - /// - internal void PopTag(uint oldTag) - { - tagLimit = oldTag; - } - /// /// Returns whether or not all the data before the limit has been read. /// @@ -1041,14 +1013,6 @@ internal bool ReachedLimit } } - internal bool ReachedTagLimit - { - get - { - return tagLimit == lastTag; - } - } - /// /// Returns true if the stream has reached the end of the input. This is the /// case if either the end of the underlying input source has been reached or diff --git a/csharp/src/Google.Protobuf/UnknownFieldSet.cs b/csharp/src/Google.Protobuf/UnknownFieldSet.cs index 6a92fb9d97d9..9121567621a1 100644 --- a/csharp/src/Google.Protobuf/UnknownFieldSet.cs +++ b/csharp/src/Google.Protobuf/UnknownFieldSet.cs @@ -183,7 +183,7 @@ internal UnknownFieldSet AddOrReplaceField(int number, UnknownField field) /// /// The coded input stream containing the field /// false if the tag is an "end group" tag, true otherwise - private void MergeFieldFrom(CodedInputStream input) + private bool MergeFieldFrom(CodedInputStream input) { uint tag = input.LastTag; int number = WireFormat.GetTagFieldNumber(tag); @@ -193,25 +193,25 @@ private void MergeFieldFrom(CodedInputStream input) { ulong uint64 = input.ReadUInt64(); GetOrAddField(number).AddVarint(uint64); - return; + return true; } case WireFormat.WireType.Fixed32: { uint uint32 = input.ReadFixed32(); GetOrAddField(number).AddFixed32(uint32); - return; + return true; } case WireFormat.WireType.Fixed64: { ulong uint64 = input.ReadFixed64(); GetOrAddField(number).AddFixed64(uint64); - return; + return true; } case WireFormat.WireType.LengthDelimited: { ByteString bytes = input.ReadBytes(); GetOrAddField(number).AddLengthDelimited(bytes); - return; + return true; } case WireFormat.WireType.StartGroup: { @@ -222,11 +222,11 @@ private void MergeFieldFrom(CodedInputStream input) set.MergeFieldFrom(input); } GetOrAddField(number).AddGroup(set); - return; + return true; } case WireFormat.WireType.EndGroup: { - throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); + return false; } default: throw new InvalidOperationException("Wire Type is invalid."); @@ -254,8 +254,34 @@ private void MergeFieldFrom(CodedInputStream input) { unknownFields = new UnknownFieldSet(); } - unknownFields.MergeFieldFrom(input); + if (!unknownFields.MergeFieldFrom(input)) + { + throw new InvalidProtocolBufferException("Merge an unknown field of end-group tag, indicating that the corresponding start-group was missing."); // match the old code-gen + } return unknownFields; + } + + /// + /// Create a new UnknownFieldSet if unknownFields is null. + /// Parse a single field from and merge it + /// into unknownFields. If is configured to discard unknown fields, + /// will be returned as-is and the field will be skipped. + /// + /// The UnknownFieldSet which need to be merged + /// The coded input stream containing the field + /// The merged UnknownFieldSet + public static bool MergeFieldFrom(ref UnknownFieldSet unknownFields, CodedInputStream input) + { + if (input.DiscardUnknownFields) + { + input.SkipLastField(); + return true; + } + if (unknownFields == null) + { + unknownFields = new UnknownFieldSet(); + } + return unknownFields.MergeFieldFrom(input); } /// From 6864106f09da8dd3493cee6010a4dd688a862d0c Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Thu, 1 Nov 2018 16:40:14 -0500 Subject: [PATCH 09/11] Write group end tags in repeated fields --- csharp/src/Google.Protobuf/Collections/RepeatedField.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs index 613ca9c48e7f..827bc711832b 100644 --- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs +++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs @@ -208,6 +208,10 @@ public void WriteTo(CodedOutputStream output, FieldCodec codec) { output.WriteTag(tag); writer(output, array[i]); + if (codec.EndTag != 0) + { + output.WriteTag(codec.EndTag); + } } } } From 75b63516675f7a9206509851a77cfc92c1543601 Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Thu, 1 Nov 2018 17:28:50 -0500 Subject: [PATCH 10/11] Readability review --- .../compiler/csharp/csharp_message_field.cc | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index 3db69dd546a2..899cd7bf7bd9 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -268,25 +268,18 @@ void MessageOneofFieldGenerator::GenerateMergingCode(io::Printer* printer) { void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) { // TODO(jonskeet): We may be able to do better than this + printer->Print( + variables_, + "$type_name$ subBuilder = new $type_name$();\n" + "if ($has_property_check$) {\n" + " subBuilder.MergeFrom($property_name$);\n" + "}\n"); if (descriptor_->type() == FieldDescriptor::Type::TYPE_MESSAGE) { - printer->Print( - variables_, - "$type_name$ subBuilder = new $type_name$();\n" - "if ($has_property_check$) {\n" - " subBuilder.MergeFrom($property_name$);\n" - "}\n" - "input.ReadMessage(subBuilder);\n" - "$property_name$ = subBuilder;\n"); + printer->Print("input.ReadMessage(subBuilder);\n"); } else { - printer->Print( - variables_, - "$type_name$ subBuilder = new $type_name$();\n" - "if ($has_property_check$) {\n" - " subBuilder.MergeFrom($property_name$);\n" - "}\n" - "input.ReadGroup(subBuilder);\n" - "$property_name$ = subBuilder;\n"); + printer->Print("input.ReadGroup(subBuilder);\n"); } + printer->Print(variables_, "$property_name$ = subBuilder;\n"); } void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) { From 1f97065400662212bff6e3e3db854de03e7a04ca Mon Sep 17 00:00:00 2001 From: ObsidianMinor Date: Thu, 1 Nov 2018 19:02:37 -0500 Subject: [PATCH 11/11] Remove C# group files from libprotoc.cmake --- BUILD | 2 -- cmake/libprotoc.cmake | 2 -- 2 files changed, 4 deletions(-) diff --git a/BUILD b/BUILD index 649451b35110..58d7a82bfd27 100644 --- a/BUILD +++ b/BUILD @@ -301,12 +301,10 @@ cc_library( "src/google/protobuf/compiler/csharp/csharp_map_field.cc", "src/google/protobuf/compiler/csharp/csharp_message.cc", "src/google/protobuf/compiler/csharp/csharp_message_field.cc", - "src/google/protobuf/compiler/csharp/csharp_group_field.cc", "src/google/protobuf/compiler/csharp/csharp_primitive_field.cc", "src/google/protobuf/compiler/csharp/csharp_reflection_class.cc", "src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc", "src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc", - "src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc", "src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc", "src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc", "src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc", diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 0a956f0d401d..850a85a67534 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -24,12 +24,10 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_map_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_group_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc - ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_group_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc ${protobuf_source_dir}/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc