Merge pull request #5936 from ObsidianMinor/csharp/proto2-feature/finale
C# Proto2 feature : Finale
This commit is contained in:
commit
37bf540fd0
@ -68,9 +68,12 @@ csharp_EXTRA_DIST= \
|
||||
csharp/protos/map_unittest_proto3.proto \
|
||||
csharp/protos/unittest_custom_options_proto3.proto \
|
||||
csharp/protos/unittest_import_public_proto3.proto \
|
||||
csharp/protos/unittest_import_public.proto \
|
||||
csharp/protos/unittest_import_proto3.proto \
|
||||
csharp/protos/unittest_import.proto \
|
||||
csharp/protos/unittest_issues.proto \
|
||||
csharp/protos/unittest_proto3.proto \
|
||||
csharp/protos/unittest.proto \
|
||||
csharp/src/AddressBook/AddPerson.cs \
|
||||
csharp/src/AddressBook/Addressbook.cs \
|
||||
csharp/src/AddressBook/AddressBook.csproj \
|
||||
@ -100,9 +103,11 @@ csharp_EXTRA_DIST= \
|
||||
csharp/src/Google.Protobuf.Test/Compatibility/TypeExtensionsTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/DeprecatedMemberTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/EqualityTester.cs \
|
||||
csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/FieldCodecTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/FieldMaskTreeTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs \
|
||||
csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj \
|
||||
csharp/src/Google.Protobuf.Test/IssuesTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs \
|
||||
@ -119,13 +124,17 @@ csharp_EXTRA_DIST= \
|
||||
csharp/src/Google.Protobuf.Test/TestCornerCases.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto2.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto3.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestCustomOptionsProto3.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublic.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImport.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs \
|
||||
csharp/src/Google.Protobuf.Test/TestProtos/Unittest.cs \
|
||||
csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs \
|
||||
csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs \
|
||||
|
@ -52,8 +52,12 @@ $PROTOC -Isrc -Icsharp/protos \
|
||||
csharp/protos/unittest_proto3.proto \
|
||||
csharp/protos/unittest_import_proto3.proto \
|
||||
csharp/protos/unittest_import_public_proto3.proto \
|
||||
csharp/protos/unittest.proto \
|
||||
csharp/protos/unittest_import.proto \
|
||||
csharp/protos/unittest_import_public.proto \
|
||||
src/google/protobuf/unittest_well_known_types.proto \
|
||||
src/google/protobuf/test_messages_proto3.proto
|
||||
src/google/protobuf/test_messages_proto3.proto \
|
||||
src/google/protobuf/test_messages_proto2.proto
|
||||
|
||||
# AddressBook sample protos
|
||||
$PROTOC -Iexamples -Isrc --csharp_out=csharp/src/AddressBook \
|
||||
|
1113
csharp/protos/unittest.proto
Normal file
1113
csharp/protos/unittest.proto
Normal file
File diff suppressed because it is too large
Load Diff
69
csharp/protos/unittest_import.proto
Normal file
69
csharp/protos/unittest_import.proto
Normal file
@ -0,0 +1,69 @@
|
||||
// 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.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// A proto file which is imported by unittest.proto to test importing.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
// We don't put this in a package within proto2 because we need to make sure
|
||||
// that the generated code doesn't depend on being in the proto2 namespace.
|
||||
// In test_util.h we do
|
||||
// "using namespace unittest_import = protobuf_unittest_import".
|
||||
package protobuf_unittest_import_proto2;
|
||||
|
||||
option optimize_for = SPEED;
|
||||
option cc_enable_arenas = true;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.TestProtos.Proto2";
|
||||
|
||||
// Test public import
|
||||
import public "unittest_import_public.proto";
|
||||
|
||||
message ImportMessage {
|
||||
optional int32 d = 1;
|
||||
}
|
||||
|
||||
enum ImportEnum {
|
||||
IMPORT_FOO = 7;
|
||||
IMPORT_BAR = 8;
|
||||
IMPORT_BAZ = 9;
|
||||
}
|
||||
|
||||
|
||||
// To use an enum in a map, it must has the first value as 0.
|
||||
enum ImportEnumForMap {
|
||||
UNKNOWN = 0;
|
||||
FOO = 1;
|
||||
BAR = 2;
|
||||
}
|
41
csharp/protos/unittest_import_public.proto
Normal file
41
csharp/protos/unittest_import_public.proto
Normal file
@ -0,0 +1,41 @@
|
||||
// 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.
|
||||
|
||||
// Author: liujisi@google.com (Pherl Liu)
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package protobuf_unittest_import_proto2;
|
||||
|
||||
option csharp_namespace = "Google.Protobuf.TestProtos.Proto2";
|
||||
|
||||
message PublicImportMessage {
|
||||
optional int32 e = 1;
|
||||
}
|
@ -48,7 +48,9 @@ namespace Google.Protobuf.Conformance
|
||||
// This way we get the binary streams instead of readers/writers.
|
||||
var input = new BinaryReader(Console.OpenStandardInput());
|
||||
var output = new BinaryWriter(Console.OpenStandardOutput());
|
||||
var typeRegistry = TypeRegistry.FromMessages(ProtobufTestMessages.Proto3.TestAllTypesProto3.Descriptor);
|
||||
var typeRegistry = TypeRegistry.FromMessages(
|
||||
ProtobufTestMessages.Proto3.TestAllTypesProto3.Descriptor,
|
||||
ProtobufTestMessages.Proto2.TestAllTypesProto2.Descriptor);
|
||||
|
||||
int count = 0;
|
||||
while (RunTest(input, output, typeRegistry))
|
||||
@ -81,7 +83,7 @@ namespace Google.Protobuf.Conformance
|
||||
|
||||
private static ConformanceResponse PerformRequest(ConformanceRequest request, TypeRegistry typeRegistry)
|
||||
{
|
||||
ProtobufTestMessages.Proto3.TestAllTypesProto3 message;
|
||||
IMessage message;
|
||||
try
|
||||
{
|
||||
switch (request.PayloadCase)
|
||||
@ -101,7 +103,13 @@ namespace Google.Protobuf.Conformance
|
||||
}
|
||||
else if (request.MessageType.Equals("protobuf_test_messages.proto2.TestAllTypesProto2"))
|
||||
{
|
||||
return new ConformanceResponse { Skipped = "CSharp doesn't support proto2" };
|
||||
ExtensionRegistry registry = new ExtensionRegistry()
|
||||
{
|
||||
ProtobufTestMessages.Proto2.TestMessagesProto2Extensions.ExtensionInt32,
|
||||
ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension1.Extensions.MessageSetExtension,
|
||||
ProtobufTestMessages.Proto2.TestAllTypesProto2.Types.MessageSetCorrectExtension2.Extensions.MessageSetExtension
|
||||
};
|
||||
message = ProtobufTestMessages.Proto2.TestAllTypesProto2.Parser.WithExtensionRegistry(registry).ParseFrom(request.ProtobufPayload);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
102
csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
Normal file
102
csharp/src/Google.Protobuf.Test/ExtensionSetTest.cs
Normal file
@ -0,0 +1,102 @@
|
||||
using Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
|
||||
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
public class ExtensionSetTest
|
||||
{
|
||||
[Test]
|
||||
public void EmptyExtensionSet()
|
||||
{
|
||||
ExtensionSet<TestAllExtensions> extensions = new ExtensionSet<TestAllExtensions>();
|
||||
Assert.AreEqual(0, extensions.CalculateSize());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MergeExtensionSet()
|
||||
{
|
||||
ExtensionSet<TestAllExtensions> extensions = null;
|
||||
ExtensionSet.Set(ref extensions, OptionalBoolExtension, true);
|
||||
|
||||
ExtensionSet<TestAllExtensions> other = null;
|
||||
|
||||
Assert.IsFalse(ExtensionSet.Has(ref other, OptionalBoolExtension));
|
||||
ExtensionSet.MergeFrom(ref other, extensions);
|
||||
Assert.IsTrue(ExtensionSet.Has(ref other, OptionalBoolExtension));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMergeCodedInput()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
message.SetExtension(OptionalBoolExtension, true);
|
||||
var serialized = message.ToByteArray();
|
||||
|
||||
var other = TestAllExtensions.Parser
|
||||
.WithExtensionRegistry(new ExtensionRegistry() { OptionalBoolExtension })
|
||||
.ParseFrom(serialized);
|
||||
|
||||
Assert.AreEqual(message, other);
|
||||
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMergeMessage()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
message.SetExtension(OptionalBoolExtension, true);
|
||||
|
||||
var other = new TestAllExtensions();
|
||||
|
||||
Assert.AreNotEqual(message, other);
|
||||
Assert.AreNotEqual(message.CalculateSize(), other.CalculateSize());
|
||||
|
||||
other.MergeFrom(message);
|
||||
|
||||
Assert.AreEqual(message, other);
|
||||
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEquals()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
message.SetExtension(OptionalBoolExtension, true);
|
||||
|
||||
var other = new TestAllExtensions();
|
||||
|
||||
Assert.AreNotEqual(message, other);
|
||||
Assert.AreNotEqual(message.CalculateSize(), other.CalculateSize());
|
||||
|
||||
other.SetExtension(OptionalBoolExtension, true);
|
||||
|
||||
Assert.AreEqual(message, other);
|
||||
Assert.AreEqual(message.CalculateSize(), other.CalculateSize());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHashCode()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
var hashCode = message.GetHashCode();
|
||||
|
||||
message.SetExtension(OptionalBoolExtension, true);
|
||||
|
||||
Assert.AreNotEqual(hashCode, message.GetHashCode());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClone()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
message.SetExtension(OptionalBoolExtension, true);
|
||||
|
||||
var other = message.Clone();
|
||||
|
||||
Assert.AreEqual(message, other);
|
||||
Assert.AreEqual(message.CalculateSize(), message.CalculateSize());
|
||||
}
|
||||
}
|
||||
}
|
368
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
Normal file
368
csharp/src/Google.Protobuf.Test/GeneratedMessageTest.Proto2.cs
Normal file
@ -0,0 +1,368 @@
|
||||
using Google.Protobuf.TestProtos.Proto2;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
|
||||
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests around the generated TestAllTypes message in unittest.proto
|
||||
/// </summary>
|
||||
public partial class GeneratedMessageTest
|
||||
{
|
||||
[Test]
|
||||
public void DefaultProto2Values()
|
||||
{
|
||||
var message = new TestAllTypes();
|
||||
Assert.AreEqual(false, message.OptionalBool);
|
||||
Assert.AreEqual(ByteString.Empty, message.OptionalBytes);
|
||||
Assert.AreEqual(0.0, message.OptionalDouble);
|
||||
Assert.AreEqual(0, message.OptionalFixed32);
|
||||
Assert.AreEqual(0L, message.OptionalFixed64);
|
||||
Assert.AreEqual(0.0f, message.OptionalFloat);
|
||||
Assert.AreEqual(ForeignEnum.ForeignFoo, message.OptionalForeignEnum);
|
||||
Assert.IsNull(message.OptionalForeignMessage);
|
||||
Assert.AreEqual(ImportEnum.ImportFoo, message.OptionalImportEnum);
|
||||
Assert.IsNull(message.OptionalImportMessage);
|
||||
Assert.AreEqual(0, message.OptionalInt32);
|
||||
Assert.AreEqual(0L, message.OptionalInt64);
|
||||
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.OptionalNestedEnum);
|
||||
Assert.IsNull(message.OptionalNestedMessage);
|
||||
Assert.IsNull(message.OptionalPublicImportMessage);
|
||||
Assert.AreEqual(0, message.OptionalSfixed32);
|
||||
Assert.AreEqual(0L, message.OptionalSfixed64);
|
||||
Assert.AreEqual(0, message.OptionalSint32);
|
||||
Assert.AreEqual(0L, message.OptionalSint64);
|
||||
Assert.AreEqual("", message.OptionalString);
|
||||
Assert.AreEqual(0U, message.OptionalUint32);
|
||||
Assert.AreEqual(0UL, message.OptionalUint64);
|
||||
|
||||
// Repeated fields
|
||||
Assert.AreEqual(0, message.RepeatedBool.Count);
|
||||
Assert.AreEqual(0, message.RepeatedBytes.Count);
|
||||
Assert.AreEqual(0, message.RepeatedDouble.Count);
|
||||
Assert.AreEqual(0, message.RepeatedFixed32.Count);
|
||||
Assert.AreEqual(0, message.RepeatedFixed64.Count);
|
||||
Assert.AreEqual(0, message.RepeatedFloat.Count);
|
||||
Assert.AreEqual(0, message.RepeatedForeignEnum.Count);
|
||||
Assert.AreEqual(0, message.RepeatedForeignMessage.Count);
|
||||
Assert.AreEqual(0, message.RepeatedImportEnum.Count);
|
||||
Assert.AreEqual(0, message.RepeatedImportMessage.Count);
|
||||
Assert.AreEqual(0, message.RepeatedNestedEnum.Count);
|
||||
Assert.AreEqual(0, message.RepeatedNestedMessage.Count);
|
||||
Assert.AreEqual(0, message.RepeatedSfixed32.Count);
|
||||
Assert.AreEqual(0, message.RepeatedSfixed64.Count);
|
||||
Assert.AreEqual(0, message.RepeatedSint32.Count);
|
||||
Assert.AreEqual(0, message.RepeatedSint64.Count);
|
||||
Assert.AreEqual(0, message.RepeatedString.Count);
|
||||
Assert.AreEqual(0, message.RepeatedUint32.Count);
|
||||
Assert.AreEqual(0, message.RepeatedUint64.Count);
|
||||
|
||||
// Oneof fields
|
||||
Assert.AreEqual(Proto2.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
|
||||
Assert.AreEqual(0, message.OneofUint32);
|
||||
Assert.AreEqual("", message.OneofString);
|
||||
Assert.AreEqual(ByteString.Empty, message.OneofBytes);
|
||||
Assert.IsNull(message.OneofNestedMessage);
|
||||
|
||||
Assert.AreEqual(true, message.DefaultBool);
|
||||
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.DefaultBytes);
|
||||
Assert.AreEqual("123", message.DefaultCord);
|
||||
Assert.AreEqual(52e3, message.DefaultDouble);
|
||||
Assert.AreEqual(47, message.DefaultFixed32);
|
||||
Assert.AreEqual(48, message.DefaultFixed64);
|
||||
Assert.AreEqual(51.5, message.DefaultFloat);
|
||||
Assert.AreEqual(ForeignEnum.ForeignBar, message.DefaultForeignEnum);
|
||||
Assert.AreEqual(ImportEnum.ImportBar, message.DefaultImportEnum);
|
||||
Assert.AreEqual(41, message.DefaultInt32);
|
||||
Assert.AreEqual(42, message.DefaultInt64);
|
||||
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.DefaultNestedEnum);
|
||||
Assert.AreEqual(49, message.DefaultSfixed32);
|
||||
Assert.AreEqual(-50, message.DefaultSfixed64);
|
||||
Assert.AreEqual(-45, message.DefaultSint32);
|
||||
Assert.AreEqual(46, message.DefaultSint64);
|
||||
Assert.AreEqual("hello", message.DefaultString);
|
||||
Assert.AreEqual("abc", message.DefaultStringPiece);
|
||||
Assert.AreEqual(43, message.DefaultUint32);
|
||||
Assert.AreEqual(44, message.DefaultUint64);
|
||||
|
||||
Assert.False(message.HasDefaultBool);
|
||||
Assert.False(message.HasDefaultBytes);
|
||||
Assert.False(message.HasDefaultCord);
|
||||
Assert.False(message.HasDefaultDouble);
|
||||
Assert.False(message.HasDefaultFixed32);
|
||||
Assert.False(message.HasDefaultFixed64);
|
||||
Assert.False(message.HasDefaultFloat);
|
||||
Assert.False(message.HasDefaultForeignEnum);
|
||||
Assert.False(message.HasDefaultImportEnum);
|
||||
Assert.False(message.HasDefaultInt32);
|
||||
Assert.False(message.HasDefaultInt64);
|
||||
Assert.False(message.HasDefaultNestedEnum);
|
||||
Assert.False(message.HasDefaultSfixed32);
|
||||
Assert.False(message.HasDefaultSfixed64);
|
||||
Assert.False(message.HasDefaultSint32);
|
||||
Assert.False(message.HasDefaultSint64);
|
||||
Assert.False(message.HasDefaultString);
|
||||
Assert.False(message.HasDefaultStringPiece);
|
||||
Assert.False(message.HasDefaultUint32);
|
||||
Assert.False(message.HasDefaultUint64);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefaultExtensionValues()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
Assert.AreEqual(false, message.GetExtension(OptionalBoolExtension));
|
||||
Assert.AreEqual(ByteString.Empty, message.GetExtension(OptionalBytesExtension));
|
||||
Assert.AreEqual(0.0, message.GetExtension(OptionalDoubleExtension));
|
||||
Assert.AreEqual(0, message.GetExtension(OptionalFixed32Extension));
|
||||
Assert.AreEqual(0L, message.GetExtension(OptionalFixed64Extension));
|
||||
Assert.AreEqual(0.0f, message.GetExtension(OptionalFloatExtension));
|
||||
Assert.AreEqual(ForeignEnum.ForeignFoo, message.GetExtension(OptionalForeignEnumExtension));
|
||||
Assert.IsNull(message.GetExtension(OptionalForeignMessageExtension));
|
||||
Assert.AreEqual(ImportEnum.ImportFoo, message.GetExtension(OptionalImportEnumExtension));
|
||||
Assert.IsNull(message.GetExtension(OptionalImportMessageExtension));
|
||||
Assert.AreEqual(0, message.GetExtension(OptionalInt32Extension));
|
||||
Assert.AreEqual(0L, message.GetExtension(OptionalInt64Extension));
|
||||
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Foo, message.GetExtension(OptionalNestedEnumExtension));
|
||||
Assert.IsNull(message.GetExtension(OptionalNestedMessageExtension));
|
||||
Assert.IsNull(message.GetExtension(OptionalPublicImportMessageExtension));
|
||||
Assert.AreEqual(0, message.GetExtension(OptionalSfixed32Extension));
|
||||
Assert.AreEqual(0L, message.GetExtension(OptionalSfixed64Extension));
|
||||
Assert.AreEqual(0, message.GetExtension(OptionalSint32Extension));
|
||||
Assert.AreEqual(0L, message.GetExtension(OptionalSint64Extension));
|
||||
Assert.AreEqual("", message.GetExtension(OptionalStringExtension));
|
||||
Assert.AreEqual(0U, message.GetExtension(OptionalUint32Extension));
|
||||
Assert.AreEqual(0UL, message.GetExtension(OptionalUint64Extension));
|
||||
|
||||
// Repeated fields
|
||||
Assert.IsNull(message.GetExtension(RepeatedBoolExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedBytesExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedDoubleExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedFixed32Extension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedFixed64Extension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedFloatExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedForeignEnumExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedForeignMessageExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedImportEnumExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedImportMessageExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedNestedEnumExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedNestedMessageExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedSfixed32Extension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedSfixed64Extension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedSint32Extension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedSint64Extension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedStringExtension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedUint32Extension));
|
||||
Assert.IsNull(message.GetExtension(RepeatedUint64Extension));
|
||||
|
||||
// Oneof fields
|
||||
Assert.AreEqual(0, message.GetExtension(OneofUint32Extension));
|
||||
Assert.AreEqual("", message.GetExtension(OneofStringExtension));
|
||||
Assert.AreEqual(ByteString.Empty, message.GetExtension(OneofBytesExtension));
|
||||
Assert.IsNull(message.GetExtension(OneofNestedMessageExtension));
|
||||
|
||||
Assert.AreEqual(true, message.GetExtension(DefaultBoolExtension));
|
||||
Assert.AreEqual(ByteString.CopyFromUtf8("world"), message.GetExtension(DefaultBytesExtension));
|
||||
Assert.AreEqual("123", message.GetExtension(DefaultCordExtension));
|
||||
Assert.AreEqual(52e3, message.GetExtension(DefaultDoubleExtension));
|
||||
Assert.AreEqual(47, message.GetExtension(DefaultFixed32Extension));
|
||||
Assert.AreEqual(48, message.GetExtension(DefaultFixed64Extension));
|
||||
Assert.AreEqual(51.5, message.GetExtension(DefaultFloatExtension));
|
||||
Assert.AreEqual(ForeignEnum.ForeignBar, message.GetExtension(DefaultForeignEnumExtension));
|
||||
Assert.AreEqual(ImportEnum.ImportBar, message.GetExtension(DefaultImportEnumExtension));
|
||||
Assert.AreEqual(41, message.GetExtension(DefaultInt32Extension));
|
||||
Assert.AreEqual(42, message.GetExtension(DefaultInt64Extension));
|
||||
Assert.AreEqual(Proto2.TestAllTypes.Types.NestedEnum.Bar, message.GetExtension(DefaultNestedEnumExtension));
|
||||
Assert.AreEqual(49, message.GetExtension(DefaultSfixed32Extension));
|
||||
Assert.AreEqual(-50, message.GetExtension(DefaultSfixed64Extension));
|
||||
Assert.AreEqual(-45, message.GetExtension(DefaultSint32Extension));
|
||||
Assert.AreEqual(46, message.GetExtension(DefaultSint64Extension));
|
||||
Assert.AreEqual("hello", message.GetExtension(DefaultStringExtension));
|
||||
Assert.AreEqual("abc", message.GetExtension(DefaultStringPieceExtension));
|
||||
Assert.AreEqual(43, message.GetExtension(DefaultUint32Extension));
|
||||
Assert.AreEqual(44, message.GetExtension(DefaultUint64Extension));
|
||||
|
||||
Assert.False(message.HasExtension(DefaultBoolExtension));
|
||||
Assert.False(message.HasExtension(DefaultBytesExtension));
|
||||
Assert.False(message.HasExtension(DefaultCordExtension));
|
||||
Assert.False(message.HasExtension(DefaultDoubleExtension));
|
||||
Assert.False(message.HasExtension(DefaultFixed32Extension));
|
||||
Assert.False(message.HasExtension(DefaultFixed64Extension));
|
||||
Assert.False(message.HasExtension(DefaultFloatExtension));
|
||||
Assert.False(message.HasExtension(DefaultForeignEnumExtension));
|
||||
Assert.False(message.HasExtension(DefaultImportEnumExtension));
|
||||
Assert.False(message.HasExtension(DefaultInt32Extension));
|
||||
Assert.False(message.HasExtension(DefaultInt64Extension));
|
||||
Assert.False(message.HasExtension(DefaultNestedEnumExtension));
|
||||
Assert.False(message.HasExtension(DefaultSfixed32Extension));
|
||||
Assert.False(message.HasExtension(DefaultSfixed64Extension));
|
||||
Assert.False(message.HasExtension(DefaultSint32Extension));
|
||||
Assert.False(message.HasExtension(DefaultSint64Extension));
|
||||
Assert.False(message.HasExtension(DefaultStringExtension));
|
||||
Assert.False(message.HasExtension(DefaultStringPieceExtension));
|
||||
Assert.False(message.HasExtension(DefaultUint32Extension));
|
||||
Assert.False(message.HasExtension(DefaultUint64Extension));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FieldPresence()
|
||||
{
|
||||
var message = new TestAllTypes();
|
||||
|
||||
Assert.False(message.HasOptionalBool);
|
||||
Assert.False(message.OptionalBool);
|
||||
|
||||
message.OptionalBool = true;
|
||||
|
||||
Assert.True(message.HasOptionalBool);
|
||||
Assert.True(message.OptionalBool);
|
||||
|
||||
message.OptionalBool = false;
|
||||
|
||||
Assert.True(message.HasOptionalBool);
|
||||
Assert.False(message.OptionalBool);
|
||||
|
||||
message.ClearOptionalBool();
|
||||
|
||||
Assert.False(message.HasOptionalBool);
|
||||
Assert.False(message.OptionalBool);
|
||||
|
||||
Assert.False(message.HasDefaultBool);
|
||||
Assert.True(message.DefaultBool);
|
||||
|
||||
message.DefaultBool = false;
|
||||
|
||||
Assert.True(message.HasDefaultBool);
|
||||
Assert.False(message.DefaultBool);
|
||||
|
||||
message.DefaultBool = true;
|
||||
|
||||
Assert.True(message.HasDefaultBool);
|
||||
Assert.True(message.DefaultBool);
|
||||
|
||||
message.ClearDefaultBool();
|
||||
|
||||
Assert.False(message.HasDefaultBool);
|
||||
Assert.True(message.DefaultBool);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RequiredFields()
|
||||
{
|
||||
var message = new TestRequired();
|
||||
Assert.False(message.IsInitialized());
|
||||
|
||||
message.A = 1;
|
||||
message.B = 2;
|
||||
message.C = 3;
|
||||
|
||||
Assert.True(message.IsInitialized());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RequiredFieldsInExtensions()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
Assert.True(message.IsInitialized());
|
||||
|
||||
message.SetExtension(TestRequired.Extensions.Single, new TestRequired());
|
||||
|
||||
Assert.False(message.IsInitialized());
|
||||
|
||||
var extensionMessage = message.GetExtension(TestRequired.Extensions.Single);
|
||||
extensionMessage.A = 1;
|
||||
extensionMessage.B = 2;
|
||||
extensionMessage.C = 3;
|
||||
|
||||
Assert.True(message.IsInitialized());
|
||||
|
||||
message.GetOrInitializeExtension(TestRequired.Extensions.Multi);
|
||||
|
||||
Assert.True(message.IsInitialized());
|
||||
|
||||
message.GetExtension(TestRequired.Extensions.Multi).Add(new TestRequired());
|
||||
|
||||
Assert.False(message.IsInitialized());
|
||||
|
||||
extensionMessage = message.GetExtension(TestRequired.Extensions.Multi)[0];
|
||||
extensionMessage.A = 1;
|
||||
extensionMessage.B = 2;
|
||||
extensionMessage.C = 3;
|
||||
|
||||
Assert.True(message.IsInitialized());
|
||||
|
||||
message.SetExtension(UnittestExtensions.OptionalBoolExtension, true);
|
||||
|
||||
Assert.True(message.IsInitialized());
|
||||
|
||||
message.GetOrInitializeExtension(UnittestExtensions.RepeatedBoolExtension).Add(true);
|
||||
|
||||
Assert.True(message.IsInitialized());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RequiredFieldInNestedMessageMapValue()
|
||||
{
|
||||
var message = new TestRequiredMap();
|
||||
message.Foo.Add(0, new TestRequiredMap.Types.NestedMessage());
|
||||
|
||||
Assert.False(message.IsInitialized());
|
||||
|
||||
message.Foo[0].RequiredInt32 = 12;
|
||||
|
||||
Assert.True(message.IsInitialized());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RoundTrip_Groups()
|
||||
{
|
||||
var message = new TestAllTypes
|
||||
{
|
||||
OptionalGroup = new TestAllTypes.Types.OptionalGroup
|
||||
{
|
||||
A = 10
|
||||
},
|
||||
RepeatedGroup =
|
||||
{
|
||||
new TestAllTypes.Types.RepeatedGroup { A = 10 },
|
||||
new TestAllTypes.Types.RepeatedGroup { A = 20 },
|
||||
new TestAllTypes.Types.RepeatedGroup { A = 30 }
|
||||
}
|
||||
};
|
||||
|
||||
byte[] bytes = message.ToByteArray();
|
||||
TestAllTypes parsed = Proto2.TestAllTypes.Parser.ParseFrom(bytes);
|
||||
Assert.AreEqual(message, parsed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RoundTrip_ExtensionGroups()
|
||||
{
|
||||
var message = new TestAllExtensions();
|
||||
message.SetExtension(UnittestExtensions.OptionalGroupExtension, new OptionalGroup_extension { A = 10 });
|
||||
message.GetOrInitializeExtension(UnittestExtensions.RepeatedGroupExtension).AddRange(new[]
|
||||
{
|
||||
new RepeatedGroup_extension { A = 10 },
|
||||
new RepeatedGroup_extension { A = 20 },
|
||||
new RepeatedGroup_extension { A = 30 }
|
||||
});
|
||||
|
||||
byte[] bytes = message.ToByteArray();
|
||||
TestAllExtensions extendable_parsed = TestAllExtensions.Parser.WithExtensionRegistry(new ExtensionRegistry() { UnittestExtensions.OptionalGroupExtension, UnittestExtensions.RepeatedGroupExtension }).ParseFrom(bytes);
|
||||
Assert.AreEqual(message, extendable_parsed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RoundTrip_NestedExtensionGroup()
|
||||
{
|
||||
var message = new TestGroupExtension();
|
||||
message.SetExtension(TestNestedExtension.Extensions.OptionalGroupExtension, new TestNestedExtension.Types.OptionalGroup_extension { A = 10 });
|
||||
|
||||
byte[] bytes = message.ToByteArray();
|
||||
TestGroupExtension extendable_parsed = TestGroupExtension.Parser.WithExtensionRegistry(new ExtensionRegistry() { TestNestedExtension.Extensions.OptionalGroupExtension }).ParseFrom(bytes);
|
||||
Assert.AreEqual(message, extendable_parsed);
|
||||
}
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@ -44,7 +45,7 @@ namespace Google.Protobuf
|
||||
/// <summary>
|
||||
/// Tests around the generated TestAllTypes message.
|
||||
/// </summary>
|
||||
public class GeneratedMessageTest
|
||||
public partial class GeneratedMessageTest
|
||||
{
|
||||
[Test]
|
||||
public void EmptyMessageFieldDistinctFromMissingMessageField()
|
||||
|
@ -33,64 +33,19 @@
|
||||
using Google.Protobuf.Reflection;
|
||||
using Google.Protobuf.WellKnownTypes;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnitTest.Issues.TestProtos;
|
||||
using static Google.Protobuf.WireFormat;
|
||||
using static UnitTest.Issues.TestProtos.ComplexOptionType2.Types;
|
||||
using static UnitTest.Issues.TestProtos.UnittestCustomOptionsProto3Extensions;
|
||||
using static UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types;
|
||||
using static Google.Protobuf.Test.Reflection.CustomOptionNumber;
|
||||
|
||||
#pragma warning disable CS0618
|
||||
|
||||
namespace Google.Protobuf.Test.Reflection
|
||||
{
|
||||
// Internal enum to allow us to use "using static" for convenience.
|
||||
// These are the options defined in unittest_custom_options_proto3.proto
|
||||
internal enum CustomOptionNumber
|
||||
{
|
||||
FileOpt1 = 7736974,
|
||||
MessageOpt1 = 7739036,
|
||||
FieldOpt1 = 7740936,
|
||||
OneofOpt1 = 7740111,
|
||||
EnumOpt1 = 7753576,
|
||||
EnumValueOpt1 = 1560678,
|
||||
ServiceOpt1 = 7887650,
|
||||
MethodOpt1 = 7890860,
|
||||
|
||||
// All message options...
|
||||
BoolOpt = 7706090,
|
||||
Int32Opt = 7705709,
|
||||
Int64Opt = 7705542,
|
||||
UInt32Opt = 7704880,
|
||||
UInt64Opt = 7702367,
|
||||
SInt32Opt = 7701568,
|
||||
SInt64Opt = 7700863,
|
||||
Fixed32Opt = 7700307,
|
||||
Fixed64Opt = 7700194,
|
||||
SFixed32Opt = 7698645,
|
||||
SFixed64Opt = 7685475,
|
||||
FloatOpt = 7675390,
|
||||
DoubleOpt = 7673293,
|
||||
StringOpt = 7673285,
|
||||
BytesOpt = 7673238,
|
||||
EnumOpt = 7673233,
|
||||
MessageTypeOpt = 7665967,
|
||||
|
||||
// Miscellaneous
|
||||
ComplexOpt4 = 7633546,
|
||||
ComplexOpt1 = 7646756,
|
||||
ComplexOpt2 = 7636949,
|
||||
ComplexOpt3 = 7636463,
|
||||
|
||||
// Aggregates
|
||||
AggregateFileOpt = 15478479,
|
||||
AggregateMsgOpt = 15480088,
|
||||
AggregateFieldOpt = 15481374,
|
||||
AggregateEnumOpt = 15483218,
|
||||
AggregateEnumValueOpt = 15486921,
|
||||
AggregateServiceOpt = 15497145,
|
||||
AggregateMethodOpt = 15512713,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The majority of the testing here is done via parsed descriptors. That's simpler to
|
||||
/// achieve (and more important) than constructing a CodedInputStream manually.
|
||||
@ -99,23 +54,41 @@ namespace Google.Protobuf.Test.Reflection
|
||||
{
|
||||
delegate bool OptionFetcher<T>(int field, out T value);
|
||||
|
||||
OptionFetcher<E> EnumFetcher<E>(CustomOptions options)
|
||||
{
|
||||
return (int i, out E v) => {
|
||||
if (options.TryGetInt32(i, out int value))
|
||||
{
|
||||
v = (E)(object)value;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = default(E);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ScalarOptions()
|
||||
{
|
||||
var options = CustomOptionOtherValues.Descriptor.CustomOptions;
|
||||
AssertOption(-100, options.TryGetInt32, Int32Opt);
|
||||
AssertOption(12.3456789f, options.TryGetFloat, FloatOpt);
|
||||
AssertOption(1.234567890123456789d, options.TryGetDouble, DoubleOpt);
|
||||
AssertOption("Hello, \"World\"", options.TryGetString, StringOpt);
|
||||
AssertOption(ByteString.CopyFromUtf8("Hello\0World"), options.TryGetBytes, BytesOpt);
|
||||
AssertOption((int)TestEnumType.TestOptionEnumType2, options.TryGetInt32, EnumOpt);
|
||||
var d = CustomOptionOtherValues.Descriptor;
|
||||
var options = d.CustomOptions;
|
||||
AssertOption(-100, options.TryGetInt32, Int32Opt, d.GetOption);
|
||||
AssertOption(12.3456789f, options.TryGetFloat, FloatOpt, d.GetOption);
|
||||
AssertOption(1.234567890123456789d, options.TryGetDouble, DoubleOpt, d.GetOption);
|
||||
AssertOption("Hello, \"World\"", options.TryGetString, StringOpt, d.GetOption);
|
||||
AssertOption(ByteString.CopyFromUtf8("Hello\0World"), options.TryGetBytes, BytesOpt, d.GetOption);
|
||||
AssertOption(TestEnumType.TestOptionEnumType2, EnumFetcher<TestEnumType>(options), EnumOpt, d.GetOption);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MessageOptions()
|
||||
{
|
||||
var options = VariousComplexOptions.Descriptor.CustomOptions;
|
||||
AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, options.TryGetMessage, ComplexOpt1);
|
||||
var d = VariousComplexOptions.Descriptor;
|
||||
var options = d.CustomOptions;
|
||||
AssertOption(new ComplexOptionType1 { Foo = 42, Foo4 = { 99, 88 } }, options.TryGetMessage, ComplexOpt1, d.GetOption);
|
||||
AssertOption(new ComplexOptionType2
|
||||
{
|
||||
Baz = 987,
|
||||
@ -123,72 +96,74 @@ namespace Google.Protobuf.Test.Reflection
|
||||
Fred = new ComplexOptionType4 { Waldo = 321 },
|
||||
Barney = { new ComplexOptionType4 { Waldo = 101 }, new ComplexOptionType4 { Waldo = 212 } }
|
||||
},
|
||||
options.TryGetMessage, ComplexOpt2);
|
||||
AssertOption(new ComplexOptionType3 { Qux = 9 }, options.TryGetMessage, ComplexOpt3);
|
||||
options.TryGetMessage, ComplexOpt2, d.GetOption);
|
||||
AssertOption(new ComplexOptionType3 { Qux = 9 }, options.TryGetMessage, ComplexOpt3, d.GetOption);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OptionLocations()
|
||||
{
|
||||
var fileOptions = UnittestCustomOptionsProto3Reflection.Descriptor.CustomOptions;
|
||||
AssertOption(9876543210UL, fileOptions.TryGetUInt64, FileOpt1);
|
||||
AssertOption(9876543210UL, fileOptions.TryGetUInt64, FileOpt1, UnittestCustomOptionsProto3Reflection.Descriptor.GetOption);
|
||||
|
||||
var messageOptions = TestMessageWithCustomOptions.Descriptor.CustomOptions;
|
||||
AssertOption(-56, messageOptions.TryGetInt32, MessageOpt1);
|
||||
AssertOption(-56, messageOptions.TryGetInt32, MessageOpt1, TestMessageWithCustomOptions.Descriptor.GetOption);
|
||||
|
||||
var fieldOptions = TestMessageWithCustomOptions.Descriptor.Fields["field1"].CustomOptions;
|
||||
AssertOption(8765432109UL, fieldOptions.TryGetFixed64, FieldOpt1);
|
||||
AssertOption(8765432109UL, fieldOptions.TryGetFixed64, FieldOpt1, TestMessageWithCustomOptions.Descriptor.Fields["field1"].GetOption);
|
||||
|
||||
var oneofOptions = TestMessageWithCustomOptions.Descriptor.Oneofs[0].CustomOptions;
|
||||
AssertOption(-99, oneofOptions.TryGetInt32, OneofOpt1);
|
||||
AssertOption(-99, oneofOptions.TryGetInt32, OneofOpt1, TestMessageWithCustomOptions.Descriptor.Oneofs[0].GetOption);
|
||||
|
||||
var enumOptions = TestMessageWithCustomOptions.Descriptor.EnumTypes[0].CustomOptions;
|
||||
AssertOption(-789, enumOptions.TryGetSFixed32, EnumOpt1);
|
||||
AssertOption(-789, enumOptions.TryGetSFixed32, EnumOpt1, TestMessageWithCustomOptions.Descriptor.EnumTypes[0].GetOption);
|
||||
|
||||
var enumValueOptions = TestMessageWithCustomOptions.Descriptor.EnumTypes[0].FindValueByNumber(2).CustomOptions;
|
||||
AssertOption(123, enumValueOptions.TryGetInt32, EnumValueOpt1);
|
||||
AssertOption(123, enumValueOptions.TryGetInt32, EnumValueOpt1, TestMessageWithCustomOptions.Descriptor.EnumTypes[0].FindValueByNumber(2).GetOption);
|
||||
|
||||
var service = UnittestCustomOptionsProto3Reflection.Descriptor.Services
|
||||
.Single(s => s.Name == "TestServiceWithCustomOptions");
|
||||
var serviceOptions = service.CustomOptions;
|
||||
AssertOption(-9876543210, serviceOptions.TryGetSInt64, ServiceOpt1);
|
||||
AssertOption(-9876543210, serviceOptions.TryGetSInt64, ServiceOpt1, service.GetOption);
|
||||
|
||||
var methodOptions = service.Methods[0].CustomOptions;
|
||||
AssertOption((int)UnitTest.Issues.TestProtos.MethodOpt1.Val2, methodOptions.TryGetInt32, CustomOptionNumber.MethodOpt1);
|
||||
AssertOption(UnitTest.Issues.TestProtos.MethodOpt1.Val2, EnumFetcher<UnitTest.Issues.TestProtos.MethodOpt1>(methodOptions), UnittestCustomOptionsProto3Extensions.MethodOpt1, service.Methods[0].GetOption);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MinValues()
|
||||
{
|
||||
var options = CustomOptionMinIntegerValues.Descriptor.CustomOptions;
|
||||
AssertOption(false, options.TryGetBool, BoolOpt);
|
||||
AssertOption(int.MinValue, options.TryGetInt32, Int32Opt);
|
||||
AssertOption(long.MinValue, options.TryGetInt64, Int64Opt);
|
||||
AssertOption(uint.MinValue, options.TryGetUInt32, UInt32Opt);
|
||||
AssertOption(ulong.MinValue, options.TryGetUInt64, UInt64Opt);
|
||||
AssertOption(int.MinValue, options.TryGetSInt32, SInt32Opt);
|
||||
AssertOption(long.MinValue, options.TryGetSInt64, SInt64Opt);
|
||||
AssertOption(uint.MinValue, options.TryGetUInt32, Fixed32Opt);
|
||||
AssertOption(ulong.MinValue, options.TryGetUInt64, Fixed64Opt);
|
||||
AssertOption(int.MinValue, options.TryGetInt32, SFixed32Opt);
|
||||
AssertOption(long.MinValue, options.TryGetInt64, SFixed64Opt);
|
||||
var d = CustomOptionMinIntegerValues.Descriptor;
|
||||
var options = d.CustomOptions;
|
||||
AssertOption(false, options.TryGetBool, BoolOpt, d.GetOption);
|
||||
AssertOption(int.MinValue, options.TryGetInt32, Int32Opt, d.GetOption);
|
||||
AssertOption(long.MinValue, options.TryGetInt64, Int64Opt, d.GetOption);
|
||||
AssertOption(uint.MinValue, options.TryGetUInt32, Uint32Opt, d.GetOption);
|
||||
AssertOption(ulong.MinValue, options.TryGetUInt64, Uint64Opt, d.GetOption);
|
||||
AssertOption(int.MinValue, options.TryGetSInt32, Sint32Opt, d.GetOption);
|
||||
AssertOption(long.MinValue, options.TryGetSInt64, Sint64Opt, d.GetOption);
|
||||
AssertOption(uint.MinValue, options.TryGetUInt32, Fixed32Opt, d.GetOption);
|
||||
AssertOption(ulong.MinValue, options.TryGetUInt64, Fixed64Opt, d.GetOption);
|
||||
AssertOption(int.MinValue, options.TryGetInt32, Sfixed32Opt, d.GetOption);
|
||||
AssertOption(long.MinValue, options.TryGetInt64, Sfixed64Opt, d.GetOption);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MaxValues()
|
||||
{
|
||||
var options = CustomOptionMaxIntegerValues.Descriptor.CustomOptions;
|
||||
AssertOption(true, options.TryGetBool, BoolOpt);
|
||||
AssertOption(int.MaxValue, options.TryGetInt32, Int32Opt);
|
||||
AssertOption(long.MaxValue, options.TryGetInt64, Int64Opt);
|
||||
AssertOption(uint.MaxValue, options.TryGetUInt32, UInt32Opt);
|
||||
AssertOption(ulong.MaxValue, options.TryGetUInt64, UInt64Opt);
|
||||
AssertOption(int.MaxValue, options.TryGetSInt32, SInt32Opt);
|
||||
AssertOption(long.MaxValue, options.TryGetSInt64, SInt64Opt);
|
||||
AssertOption(uint.MaxValue, options.TryGetFixed32, Fixed32Opt);
|
||||
AssertOption(ulong.MaxValue, options.TryGetFixed64, Fixed64Opt);
|
||||
AssertOption(int.MaxValue, options.TryGetSFixed32, SFixed32Opt);
|
||||
AssertOption(long.MaxValue, options.TryGetSFixed64, SFixed64Opt);
|
||||
var d = CustomOptionMaxIntegerValues.Descriptor;
|
||||
var options = d.CustomOptions;
|
||||
AssertOption(true, options.TryGetBool, BoolOpt, d.GetOption);
|
||||
AssertOption(int.MaxValue, options.TryGetInt32, Int32Opt, d.GetOption);
|
||||
AssertOption(long.MaxValue, options.TryGetInt64, Int64Opt, d.GetOption);
|
||||
AssertOption(uint.MaxValue, options.TryGetUInt32, Uint32Opt, d.GetOption);
|
||||
AssertOption(ulong.MaxValue, options.TryGetUInt64, Uint64Opt, d.GetOption);
|
||||
AssertOption(int.MaxValue, options.TryGetSInt32, Sint32Opt, d.GetOption);
|
||||
AssertOption(long.MaxValue, options.TryGetSInt64, Sint64Opt, d.GetOption);
|
||||
AssertOption(uint.MaxValue, options.TryGetFixed32, Fixed32Opt, d.GetOption);
|
||||
AssertOption(ulong.MaxValue, options.TryGetFixed64, Fixed64Opt, d.GetOption);
|
||||
AssertOption(int.MaxValue, options.TryGetSFixed32, Sfixed32Opt, d.GetOption);
|
||||
AssertOption(long.MaxValue, options.TryGetSFixed64, Sfixed64Opt, d.GetOption);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -196,17 +171,19 @@ namespace Google.Protobuf.Test.Reflection
|
||||
{
|
||||
// Just two examples
|
||||
var messageOptions = AggregateMessage.Descriptor.CustomOptions;
|
||||
AssertOption(new Aggregate { I = 101, S = "MessageAnnotation" }, messageOptions.TryGetMessage, AggregateMsgOpt);
|
||||
AssertOption(new Aggregate { I = 101, S = "MessageAnnotation" }, messageOptions.TryGetMessage, Msgopt, AggregateMessage.Descriptor.GetOption);
|
||||
|
||||
var fieldOptions = AggregateMessage.Descriptor.Fields["fieldname"].CustomOptions;
|
||||
AssertOption(new Aggregate { S = "FieldAnnotation" }, fieldOptions.TryGetMessage, AggregateFieldOpt);
|
||||
AssertOption(new Aggregate { S = "FieldAnnotation" }, fieldOptions.TryGetMessage, Fieldopt, AggregateMessage.Descriptor.Fields["fieldname"].GetOption);
|
||||
}
|
||||
|
||||
private void AssertOption<T>(T expected, OptionFetcher<T> fetcher, CustomOptionNumber field)
|
||||
private void AssertOption<T, D>(T expected, OptionFetcher<T> fetcher, Extension<D, T> extension, Func<Extension<D, T>, T> descriptorOptionFetcher) where D : IExtendableMessage<D>
|
||||
{
|
||||
T actual;
|
||||
Assert.IsTrue(fetcher((int)field, out actual));
|
||||
Assert.AreEqual(expected, actual);
|
||||
T customOptionsValue;
|
||||
T extensionValue = descriptorOptionFetcher(extension);
|
||||
Assert.IsTrue(fetcher(extension.FieldNumber, out customOptionsValue));
|
||||
Assert.AreEqual(expected, customOptionsValue);
|
||||
Assert.AreEqual(expected, extensionValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,11 +31,14 @@
|
||||
#endregion
|
||||
|
||||
using Google.Protobuf.TestProtos;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
public class FieldAccessTest
|
||||
@ -44,36 +47,36 @@ namespace Google.Protobuf.Reflection
|
||||
public void GetValue()
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = TestAllTypes.Descriptor.Fields;
|
||||
Assert.AreEqual(message.SingleBool, fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleBytes, fields[TestAllTypes.SingleBytesFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleDouble, fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleFixed32, fields[TestAllTypes.SingleFixed32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleFixed64, fields[TestAllTypes.SingleFixed64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleFloat, fields[TestAllTypes.SingleFloatFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleForeignEnum, fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleForeignMessage, fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleImportEnum, fields[TestAllTypes.SingleImportEnumFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleImportMessage, fields[TestAllTypes.SingleImportMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleInt32, fields[TestAllTypes.SingleInt32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleInt64, fields[TestAllTypes.SingleInt64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleNestedEnum, fields[TestAllTypes.SingleNestedEnumFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleNestedMessage, fields[TestAllTypes.SingleNestedMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SinglePublicImportMessage, fields[TestAllTypes.SinglePublicImportMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSint32, fields[TestAllTypes.SingleSint32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSint64, fields[TestAllTypes.SingleSint64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleString, fields[TestAllTypes.SingleStringFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSfixed32, fields[TestAllTypes.SingleSfixed32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSfixed64, fields[TestAllTypes.SingleSfixed64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleUint32, fields[TestAllTypes.SingleUint32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleUint64, fields[TestAllTypes.SingleUint64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofBytes, fields[TestAllTypes.OneofBytesFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofString, fields[TestAllTypes.OneofStringFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofNestedMessage, fields[TestAllTypes.OneofNestedMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofUint32, fields[TestAllTypes.OneofUint32FieldNumber].Accessor.GetValue(message));
|
||||
var fields = TestProtos.TestAllTypes.Descriptor.Fields;
|
||||
Assert.AreEqual(message.SingleBool, fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleBytes, fields[TestProtos.TestAllTypes.SingleBytesFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleDouble, fields[TestProtos.TestAllTypes.SingleDoubleFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleFixed32, fields[TestProtos.TestAllTypes.SingleFixed32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleFixed64, fields[TestProtos.TestAllTypes.SingleFixed64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleFloat, fields[TestProtos.TestAllTypes.SingleFloatFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleForeignEnum, fields[TestProtos.TestAllTypes.SingleForeignEnumFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleForeignMessage, fields[TestProtos.TestAllTypes.SingleForeignMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleImportEnum, fields[TestProtos.TestAllTypes.SingleImportEnumFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleImportMessage, fields[TestProtos.TestAllTypes.SingleImportMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleInt32, fields[TestProtos.TestAllTypes.SingleInt32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleInt64, fields[TestProtos.TestAllTypes.SingleInt64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleNestedEnum, fields[TestProtos.TestAllTypes.SingleNestedEnumFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleNestedMessage, fields[TestProtos.TestAllTypes.SingleNestedMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SinglePublicImportMessage, fields[TestProtos.TestAllTypes.SinglePublicImportMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSint32, fields[TestProtos.TestAllTypes.SingleSint32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSint64, fields[TestProtos.TestAllTypes.SingleSint64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleString, fields[TestProtos.TestAllTypes.SingleStringFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSfixed32, fields[TestProtos.TestAllTypes.SingleSfixed32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleSfixed64, fields[TestProtos.TestAllTypes.SingleSfixed64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleUint32, fields[TestProtos.TestAllTypes.SingleUint32FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.SingleUint64, fields[TestProtos.TestAllTypes.SingleUint64FieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofBytes, fields[TestProtos.TestAllTypes.OneofBytesFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofString, fields[TestProtos.TestAllTypes.OneofStringFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofNestedMessage, fields[TestProtos.TestAllTypes.OneofNestedMessageFieldNumber].Accessor.GetValue(message));
|
||||
Assert.AreEqual(message.OneofUint32, fields[TestProtos.TestAllTypes.OneofUint32FieldNumber].Accessor.GetValue(message));
|
||||
|
||||
// Just one example for repeated fields - they're all just returning the list
|
||||
var list = (IList) fields[TestAllTypes.RepeatedInt32FieldNumber].Accessor.GetValue(message);
|
||||
var list = (IList) fields[TestProtos.TestAllTypes.RepeatedInt32FieldNumber].Accessor.GetValue(message);
|
||||
Assert.AreEqual(message.RepeatedInt32, list);
|
||||
Assert.AreEqual(message.RepeatedInt32[0], list[0]); // Just in case there was any doubt...
|
||||
|
||||
@ -85,18 +88,122 @@ namespace Google.Protobuf.Reflection
|
||||
Assert.AreEqual("value1", dictionary["key1"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetValue_IncorrectType()
|
||||
{
|
||||
IMessage message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidCastException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HasValue_Proto3()
|
||||
{
|
||||
IMessage message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidOperationException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.HasValue(message));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HasValue()
|
||||
{
|
||||
IMessage message = new Proto2.TestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
var accessor = fields[Proto2.TestAllTypes.OptionalBoolFieldNumber].Accessor;
|
||||
|
||||
Assert.False(accessor.HasValue(message));
|
||||
|
||||
accessor.SetValue(message, true);
|
||||
Assert.True(accessor.HasValue(message));
|
||||
|
||||
accessor.Clear(message);
|
||||
Assert.False(accessor.HasValue(message));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_SingleFields()
|
||||
{
|
||||
// Just a sample (primitives, messages, enums, strings, byte strings)
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = TestProtos.TestAllTypes.Descriptor.Fields;
|
||||
fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, false);
|
||||
fields[TestProtos.TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500);
|
||||
fields[TestProtos.TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string");
|
||||
fields[TestProtos.TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97));
|
||||
fields[TestProtos.TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo);
|
||||
fields[TestProtos.TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
|
||||
fields[TestProtos.TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
|
||||
|
||||
var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes())
|
||||
{
|
||||
SingleBool = false,
|
||||
SingleInt32 = 500,
|
||||
SingleString = "It's a string",
|
||||
SingleBytes = ByteString.CopyFrom(99, 98, 97),
|
||||
SingleForeignEnum = ForeignEnum.ForeignFoo,
|
||||
SingleForeignMessage = new ForeignMessage { C = 12345 },
|
||||
SingleDouble = 20150701.5
|
||||
};
|
||||
|
||||
Assert.AreEqual(expected, message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_SingleFields_WrongType()
|
||||
{
|
||||
IMessage message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidCastException>(() => fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_MapFields()
|
||||
{
|
||||
IMessage message = new TestMap();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_RepeatedFields()
|
||||
{
|
||||
IMessage message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidOperationException>(() => fields[TestProtos.TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10]));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Oneof()
|
||||
{
|
||||
var message = new TestAllTypes();
|
||||
var descriptor = TestProtos.TestAllTypes.Descriptor;
|
||||
Assert.AreEqual(1, descriptor.Oneofs.Count);
|
||||
var oneof = descriptor.Oneofs[0];
|
||||
Assert.AreEqual("oneof_field", oneof.Name);
|
||||
Assert.IsNull(oneof.Accessor.GetCaseFieldDescriptor(message));
|
||||
|
||||
message.OneofString = "foo";
|
||||
Assert.AreSame(descriptor.Fields[TestProtos.TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
|
||||
|
||||
message.OneofUint32 = 10;
|
||||
Assert.AreSame(descriptor.Fields[TestProtos.TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
|
||||
|
||||
oneof.Accessor.Clear(message);
|
||||
Assert.AreEqual(TestProtos.TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Clear()
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = TestAllTypes.Descriptor.Fields;
|
||||
fields[TestAllTypes.SingleBoolFieldNumber].Accessor.Clear(message);
|
||||
fields[TestAllTypes.SingleInt32FieldNumber].Accessor.Clear(message);
|
||||
fields[TestAllTypes.SingleStringFieldNumber].Accessor.Clear(message);
|
||||
fields[TestAllTypes.SingleBytesFieldNumber].Accessor.Clear(message);
|
||||
fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.Clear(message);
|
||||
fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.Clear(message);
|
||||
fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.Clear(message);
|
||||
var fields = TestProtos.TestAllTypes.Descriptor.Fields;
|
||||
fields[TestProtos.TestAllTypes.SingleBoolFieldNumber].Accessor.Clear(message);
|
||||
fields[TestProtos.TestAllTypes.SingleInt32FieldNumber].Accessor.Clear(message);
|
||||
fields[TestProtos.TestAllTypes.SingleStringFieldNumber].Accessor.Clear(message);
|
||||
fields[TestProtos.TestAllTypes.SingleBytesFieldNumber].Accessor.Clear(message);
|
||||
fields[TestProtos.TestAllTypes.SingleForeignEnumFieldNumber].Accessor.Clear(message);
|
||||
fields[TestProtos.TestAllTypes.SingleForeignMessageFieldNumber].Accessor.Clear(message);
|
||||
fields[TestProtos.TestAllTypes.RepeatedDoubleFieldNumber].Accessor.Clear(message);
|
||||
|
||||
var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes())
|
||||
{
|
||||
@ -118,101 +225,44 @@ namespace Google.Protobuf.Reflection
|
||||
Assert.AreEqual(0, mapMessage.MapStringString.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_SingleFields()
|
||||
{
|
||||
// Just a sample (primitives, messages, enums, strings, byte strings)
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = TestAllTypes.Descriptor.Fields;
|
||||
fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, false);
|
||||
fields[TestAllTypes.SingleInt32FieldNumber].Accessor.SetValue(message, 500);
|
||||
fields[TestAllTypes.SingleStringFieldNumber].Accessor.SetValue(message, "It's a string");
|
||||
fields[TestAllTypes.SingleBytesFieldNumber].Accessor.SetValue(message, ByteString.CopyFrom(99, 98, 97));
|
||||
fields[TestAllTypes.SingleForeignEnumFieldNumber].Accessor.SetValue(message, ForeignEnum.ForeignFoo);
|
||||
fields[TestAllTypes.SingleForeignMessageFieldNumber].Accessor.SetValue(message, new ForeignMessage { C = 12345 });
|
||||
fields[TestAllTypes.SingleDoubleFieldNumber].Accessor.SetValue(message, 20150701.5);
|
||||
|
||||
var expected = new TestAllTypes(SampleMessages.CreateFullTestAllTypes())
|
||||
{
|
||||
SingleBool = false,
|
||||
SingleInt32 = 500,
|
||||
SingleString = "It's a string",
|
||||
SingleBytes = ByteString.CopyFrom(99, 98, 97),
|
||||
SingleForeignEnum = ForeignEnum.ForeignFoo,
|
||||
SingleForeignMessage = new ForeignMessage { C = 12345 },
|
||||
SingleDouble = 20150701.5
|
||||
};
|
||||
|
||||
Assert.AreEqual(expected, message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_SingleFields_WrongType()
|
||||
{
|
||||
IMessage message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.SetValue(message, "This isn't a bool"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_MapFields()
|
||||
{
|
||||
IMessage message = new TestMap();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidOperationException>(() => fields[TestMap.MapStringStringFieldNumber].Accessor.SetValue(message, new Dictionary<string, string>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_RepeatedFields()
|
||||
{
|
||||
IMessage message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidOperationException>(() => fields[TestAllTypes.RepeatedDoubleFieldNumber].Accessor.SetValue(message, new double[10]));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetValue_IncorrectType()
|
||||
{
|
||||
IMessage message = SampleMessages.CreateFullTestAllTypes();
|
||||
var fields = message.Descriptor.Fields;
|
||||
Assert.Throws<InvalidCastException>(() => fields[TestAllTypes.SingleBoolFieldNumber].Accessor.GetValue(new TestMap()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Oneof()
|
||||
{
|
||||
var message = new TestAllTypes();
|
||||
var descriptor = TestAllTypes.Descriptor;
|
||||
Assert.AreEqual(1, descriptor.Oneofs.Count);
|
||||
var oneof = descriptor.Oneofs[0];
|
||||
Assert.AreEqual("oneof_field", oneof.Name);
|
||||
Assert.IsNull(oneof.Accessor.GetCaseFieldDescriptor(message));
|
||||
|
||||
message.OneofString = "foo";
|
||||
Assert.AreSame(descriptor.Fields[TestAllTypes.OneofStringFieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
|
||||
|
||||
message.OneofUint32 = 10;
|
||||
Assert.AreSame(descriptor.Fields[TestAllTypes.OneofUint32FieldNumber], oneof.Accessor.GetCaseFieldDescriptor(message));
|
||||
|
||||
oneof.Accessor.Clear(message);
|
||||
Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.None, message.OneofFieldCase);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FieldDescriptor_ByName()
|
||||
{
|
||||
var descriptor = TestAllTypes.Descriptor;
|
||||
var descriptor = TestProtos.TestAllTypes.Descriptor;
|
||||
Assert.AreSame(
|
||||
descriptor.Fields[TestAllTypes.SingleBoolFieldNumber],
|
||||
descriptor.Fields[TestProtos.TestAllTypes.SingleBoolFieldNumber],
|
||||
descriptor.Fields["single_bool"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FieldDescriptor_NotFound()
|
||||
{
|
||||
var descriptor = TestAllTypes.Descriptor;
|
||||
var descriptor = TestProtos.TestAllTypes.Descriptor;
|
||||
Assert.Throws<KeyNotFoundException>(() => descriptor.Fields[999999].ToString());
|
||||
Assert.Throws<KeyNotFoundException>(() => descriptor.Fields["not found"].ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetExtensionValue()
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllExtensions();
|
||||
|
||||
// test that the reflector works, since the reflector just runs through IExtendableMessage
|
||||
Assert.AreEqual(message.GetExtension(OptionalBoolExtension), Proto2.TestAllExtensions.Descriptor.FindFieldByNumber(OptionalBoolExtension.FieldNumber).Accessor.GetValue(message));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetRepeatedExtensionValue()
|
||||
{
|
||||
// check to make sure repeated accessor uses GetOrRegister
|
||||
var message = new Proto2.TestAllExtensions();
|
||||
|
||||
Assert.IsNull(message.GetExtension(RepeatedBoolExtension));
|
||||
Assert.IsNotNull(Proto2.TestAllExtensions.Descriptor.FindFieldByNumber(RepeatedBoolExtension.FieldNumber).Accessor.GetValue(message));
|
||||
Assert.IsNotNull(message.GetExtension(RepeatedBoolExtension));
|
||||
|
||||
message.ClearExtension(RepeatedBoolExtension);
|
||||
Assert.IsNull(message.GetExtension(RepeatedBoolExtension));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,9 @@
|
||||
|
||||
using System;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
|
||||
using static Google.Protobuf.TestProtos.Proto2.UnittestExtensions;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@ -60,7 +63,7 @@ namespace Google.Protobuf
|
||||
SingleImportMessage = new ImportMessage { D = 20 },
|
||||
SingleInt32 = 100,
|
||||
SingleInt64 = 3210987654321,
|
||||
SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
|
||||
SingleNestedEnum = TestProtos.TestAllTypes.Types.NestedEnum.Foo,
|
||||
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
|
||||
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
|
||||
SingleSfixed32 = -123,
|
||||
@ -82,7 +85,7 @@ namespace Google.Protobuf
|
||||
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
|
||||
RepeatedInt32 = { 100, 200 },
|
||||
RepeatedInt64 = { 3210987654321, Int64.MaxValue },
|
||||
RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
|
||||
RepeatedNestedEnum = { TestProtos.TestAllTypes.Types.NestedEnum.Foo, TestProtos.TestAllTypes.Types.NestedEnum.Neg },
|
||||
RepeatedNestedMessage = { new TestAllTypes.Types.NestedMessage { Bb = 35 }, new TestAllTypes.Types.NestedMessage { Bb = 10 } },
|
||||
RepeatedPublicImportMessage = { new PublicImportMessage { E = 54 }, new PublicImportMessage { E = -1 } },
|
||||
RepeatedSfixed32 = { -123, 123 },
|
||||
@ -95,5 +98,110 @@ namespace Google.Protobuf
|
||||
OneofString = "Oneof string"
|
||||
};
|
||||
}
|
||||
|
||||
public static Proto2.TestAllTypes CreateFullTestAllTypesProto2()
|
||||
{
|
||||
return new Proto2.TestAllTypes
|
||||
{
|
||||
OptionalBool = true,
|
||||
OptionalBytes = ByteString.CopyFrom(1, 2, 3, 4),
|
||||
OptionalDouble = 23.5,
|
||||
OptionalFixed32 = 23,
|
||||
OptionalFixed64 = 1234567890123,
|
||||
OptionalFloat = 12.25f,
|
||||
OptionalForeignEnum = Proto2.ForeignEnum.ForeignBar,
|
||||
OptionalForeignMessage = new Proto2.ForeignMessage { C = 10 },
|
||||
OptionalImportEnum = Proto2.ImportEnum.ImportBaz,
|
||||
OptionalImportMessage = new Proto2.ImportMessage { D = 20 },
|
||||
OptionalInt32 = 100,
|
||||
OptionalInt64 = 3210987654321,
|
||||
OptionalNestedEnum = Proto2.TestAllTypes.Types.NestedEnum.Foo,
|
||||
OptionalNestedMessage = new Proto2.TestAllTypes.Types.NestedMessage { Bb = 35 },
|
||||
OptionalPublicImportMessage = new Proto2.PublicImportMessage { E = 54 },
|
||||
OptionalSfixed32 = -123,
|
||||
OptionalSfixed64 = -12345678901234,
|
||||
OptionalSint32 = -456,
|
||||
OptionalSint64 = -12345678901235,
|
||||
OptionalString = "test",
|
||||
OptionalUint32 = UInt32.MaxValue,
|
||||
OptionalUint64 = UInt64.MaxValue,
|
||||
OptionalGroup = new Proto2.TestAllTypes.Types.OptionalGroup { A = 10 },
|
||||
RepeatedBool = { true, false },
|
||||
RepeatedBytes = { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6), ByteString.CopyFrom(new byte[1000]) },
|
||||
RepeatedDouble = { -12.25, 23.5 },
|
||||
RepeatedFixed32 = { UInt32.MaxValue, 23 },
|
||||
RepeatedFixed64 = { UInt64.MaxValue, 1234567890123 },
|
||||
RepeatedFloat = { 100f, 12.25f },
|
||||
RepeatedForeignEnum = { Proto2.ForeignEnum.ForeignFoo, Proto2.ForeignEnum.ForeignBar },
|
||||
RepeatedForeignMessage = { new Proto2.ForeignMessage(), new Proto2.ForeignMessage { C = 10 } },
|
||||
RepeatedImportEnum = { Proto2.ImportEnum.ImportBaz, Proto2.ImportEnum.ImportFoo },
|
||||
RepeatedImportMessage = { new Proto2.ImportMessage { D = 20 }, new Proto2.ImportMessage { D = 25 } },
|
||||
RepeatedInt32 = { 100, 200 },
|
||||
RepeatedInt64 = { 3210987654321, Int64.MaxValue },
|
||||
RepeatedNestedEnum = { Proto2.TestAllTypes.Types.NestedEnum.Foo, Proto2.TestAllTypes.Types.NestedEnum.Neg },
|
||||
RepeatedNestedMessage = { new Proto2.TestAllTypes.Types.NestedMessage { Bb = 35 }, new Proto2.TestAllTypes.Types.NestedMessage { Bb = 10 } },
|
||||
RepeatedSfixed32 = { -123, 123 },
|
||||
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
|
||||
RepeatedSint32 = { -456, 100 },
|
||||
RepeatedSint64 = { -12345678901235, 123 },
|
||||
RepeatedString = { "foo", "bar" },
|
||||
RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
|
||||
RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
|
||||
RepeatedGroup = { new Proto2.TestAllTypes.Types.RepeatedGroup { A = 10 }, new Proto2.TestAllTypes.Types.RepeatedGroup { A = 20 } },
|
||||
OneofString = "Oneof string"
|
||||
};
|
||||
}
|
||||
|
||||
public static Proto2.TestAllExtensions CreateFullTestAllExtensions()
|
||||
{
|
||||
var message = new Proto2.TestAllExtensions();
|
||||
message.SetExtension(OptionalBoolExtension, true);
|
||||
message.SetExtension(OptionalBytesExtension, ByteString.CopyFrom(1, 2, 3, 4));
|
||||
message.SetExtension(OptionalDoubleExtension, 23.5);
|
||||
message.SetExtension(OptionalFixed32Extension, 23u);
|
||||
message.SetExtension(OptionalFixed64Extension, 1234567890123u);
|
||||
message.SetExtension(OptionalFloatExtension, 12.25f);
|
||||
message.SetExtension(OptionalForeignEnumExtension, Proto2.ForeignEnum.ForeignBar);
|
||||
message.SetExtension(OptionalForeignMessageExtension, new Proto2.ForeignMessage { C = 10 });
|
||||
message.SetExtension(OptionalImportEnumExtension, Proto2.ImportEnum.ImportBaz);
|
||||
message.SetExtension(OptionalImportMessageExtension, new Proto2.ImportMessage { D = 20 });
|
||||
message.SetExtension(OptionalInt32Extension, 100);
|
||||
message.SetExtension(OptionalInt64Extension, 3210987654321);
|
||||
message.SetExtension(OptionalNestedEnumExtension, Proto2.TestAllTypes.Types.NestedEnum.Foo);
|
||||
message.SetExtension(OptionalNestedMessageExtension, new Proto2.TestAllTypes.Types.NestedMessage { Bb = 35 });
|
||||
message.SetExtension(OptionalPublicImportMessageExtension, new Proto2.PublicImportMessage { E = 54 });
|
||||
message.SetExtension(OptionalSfixed32Extension, -123);
|
||||
message.SetExtension(OptionalSfixed64Extension, -12345678901234);
|
||||
message.SetExtension(OptionalSint32Extension, -456);
|
||||
message.SetExtension(OptionalSint64Extension, -12345678901235);
|
||||
message.SetExtension(OptionalStringExtension, "test");
|
||||
message.SetExtension(OptionalUint32Extension, UInt32.MaxValue);
|
||||
message.SetExtension(OptionalUint64Extension, UInt64.MaxValue);
|
||||
message.SetExtension(OptionalGroupExtension, new Proto2.OptionalGroup_extension { A = 10 });
|
||||
message.GetOrInitializeExtension(RepeatedBoolExtension).AddRange(new[] { true, false });
|
||||
message.GetOrInitializeExtension(RepeatedBytesExtension).AddRange(new[] { ByteString.CopyFrom(1, 2, 3, 4), ByteString.CopyFrom(5, 6), ByteString.CopyFrom(new byte[1000]) });
|
||||
message.GetOrInitializeExtension(RepeatedDoubleExtension).AddRange(new[] { -12.25, 23.5 });
|
||||
message.GetOrInitializeExtension(RepeatedFixed32Extension).AddRange(new[] { UInt32.MaxValue, 23u });
|
||||
message.GetOrInitializeExtension(RepeatedFixed64Extension).AddRange(new[] { UInt64.MaxValue, 1234567890123ul });
|
||||
message.GetOrInitializeExtension(RepeatedFloatExtension).AddRange(new[] { 100f, 12.25f });
|
||||
message.GetOrInitializeExtension(RepeatedForeignEnumExtension).AddRange(new[] { Proto2.ForeignEnum.ForeignFoo, Proto2.ForeignEnum.ForeignBar });
|
||||
message.GetOrInitializeExtension(RepeatedForeignMessageExtension).AddRange(new[] { new Proto2.ForeignMessage(), new Proto2.ForeignMessage { C = 10 } });
|
||||
message.GetOrInitializeExtension(RepeatedImportEnumExtension).AddRange(new[] { Proto2.ImportEnum.ImportBaz, Proto2.ImportEnum.ImportFoo });
|
||||
message.GetOrInitializeExtension(RepeatedImportMessageExtension).AddRange(new[] { new Proto2.ImportMessage { D = 20 }, new Proto2.ImportMessage { D = 25 } });
|
||||
message.GetOrInitializeExtension(RepeatedInt32Extension).AddRange(new[] { 100, 200 });
|
||||
message.GetOrInitializeExtension(RepeatedInt64Extension).AddRange(new[] { 3210987654321, Int64.MaxValue });
|
||||
message.GetOrInitializeExtension(RepeatedNestedEnumExtension).AddRange(new[] { Proto2.TestAllTypes.Types.NestedEnum.Foo, Proto2.TestAllTypes.Types.NestedEnum.Neg });
|
||||
message.GetOrInitializeExtension(RepeatedNestedMessageExtension).AddRange(new[] { new Proto2.TestAllTypes.Types.NestedMessage { Bb = 35 }, new Proto2.TestAllTypes.Types.NestedMessage { Bb = 10 } });
|
||||
message.GetOrInitializeExtension(RepeatedSfixed32Extension).AddRange(new[] { -123, 123 });
|
||||
message.GetOrInitializeExtension(RepeatedSfixed64Extension).AddRange(new[] { -12345678901234, 12345678901234 });
|
||||
message.GetOrInitializeExtension(RepeatedSint32Extension).AddRange(new[] { -456, 100 });
|
||||
message.GetOrInitializeExtension(RepeatedSint64Extension).AddRange(new[] { -12345678901235, 123 });
|
||||
message.GetOrInitializeExtension(RepeatedStringExtension).AddRange(new[] { "foo", "bar" });
|
||||
message.GetOrInitializeExtension(RepeatedUint32Extension).AddRange(new[] { UInt32.MaxValue, UInt32.MinValue });
|
||||
message.GetOrInitializeExtension(RepeatedUint64Extension).AddRange(new[] { UInt64.MaxValue, UInt32.MinValue });
|
||||
message.GetOrInitializeExtension(RepeatedGroupExtension).AddRange(new[] { new Proto2.RepeatedGroup_extension { A = 10 }, new Proto2.RepeatedGroup_extension { A = 20 } });
|
||||
message.SetExtension(OneofStringExtension, "Oneof string");
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
5403
csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto2.cs
Normal file
5403
csharp/src/Google.Protobuf.Test/TestProtos/TestMessagesProto2.cs
Normal file
File diff suppressed because it is too large
Load Diff
23941
csharp/src/Google.Protobuf.Test/TestProtos/Unittest.cs
Normal file
23941
csharp/src/Google.Protobuf.Test/TestProtos/Unittest.cs
Normal file
File diff suppressed because one or more lines are too long
@ -165,7 +165,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
|
||||
}
|
||||
/// <summary>Holder for extension identifiers generated from the top level of unittest_custom_options_proto3.proto</summary>
|
||||
internal static partial class UnittestCustomOptionsProto3Extensions {
|
||||
public static partial class UnittestCustomOptionsProto3Extensions {
|
||||
public static readonly pb::Extension<global::Google.Protobuf.Reflection.FileOptions, ulong> FileOpt1 =
|
||||
new pb::Extension<global::Google.Protobuf.Reflection.FileOptions, ulong>(7736974, pb::FieldCodec.ForUInt64(61895792, 0UL));
|
||||
public static readonly pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, int> MessageOpt1 =
|
||||
@ -2138,7 +2138,7 @@ namespace UnitTest.Issues.TestProtos {
|
||||
#region Extensions
|
||||
/// <summary>Container for extensions for other messages declared in the ComplexOptionType4 message type.</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
internal static partial class Extensions {
|
||||
public static partial class Extensions {
|
||||
public static readonly pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4> ComplexOpt4 =
|
||||
new pb::Extension<global::Google.Protobuf.Reflection.MessageOptions, global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4>(7633546, pb::FieldCodec.ForMessage(61068370, global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Parser));
|
||||
}
|
||||
|
210
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImport.cs
Normal file
210
csharp/src/Google.Protobuf.Test/TestProtos/UnittestImport.cs
Normal file
@ -0,0 +1,210 @@
|
||||
// <auto-generated>
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: unittest_import.proto
|
||||
// </auto-generated>
|
||||
#pragma warning disable 1591, 0612, 3021
|
||||
#region Designer generated code
|
||||
|
||||
using pb = global::Google.Protobuf;
|
||||
using pbc = global::Google.Protobuf.Collections;
|
||||
using pbr = global::Google.Protobuf.Reflection;
|
||||
using scg = global::System.Collections.Generic;
|
||||
namespace Google.Protobuf.TestProtos.Proto2 {
|
||||
|
||||
/// <summary>Holder for reflection information generated from unittest_import.proto</summary>
|
||||
public static partial class UnittestImportReflection {
|
||||
|
||||
#region Descriptor
|
||||
/// <summary>File descriptor for unittest_import.proto</summary>
|
||||
public static pbr::FileDescriptor Descriptor {
|
||||
get { return descriptor; }
|
||||
}
|
||||
private static pbr::FileDescriptor descriptor;
|
||||
|
||||
static UnittestImportReflection() {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"ChV1bml0dGVzdF9pbXBvcnQucHJvdG8SH3Byb3RvYnVmX3VuaXR0ZXN0X2lt",
|
||||
"cG9ydF9wcm90bzIaHHVuaXR0ZXN0X2ltcG9ydF9wdWJsaWMucHJvdG8iGgoN",
|
||||
"SW1wb3J0TWVzc2FnZRIJCgFkGAEgASgFKjwKCkltcG9ydEVudW0SDgoKSU1Q",
|
||||
"T1JUX0ZPTxAHEg4KCklNUE9SVF9CQVIQCBIOCgpJTVBPUlRfQkFaEAkqMQoQ",
|
||||
"SW1wb3J0RW51bUZvck1hcBILCgdVTktOT1dOEAASBwoDRk9PEAESBwoDQkFS",
|
||||
"EAJCKUgB+AEBqgIhR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3MuUHJvdG8y",
|
||||
"UAA="));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.Proto2.UnittestImportPublicReflection.Descriptor, },
|
||||
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.Proto2.ImportEnum), typeof(global::Google.Protobuf.TestProtos.Proto2.ImportEnumForMap), }, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Proto2.ImportMessage), global::Google.Protobuf.TestProtos.Proto2.ImportMessage.Parser, new[]{ "D" }, null, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
#region Enums
|
||||
public enum ImportEnum {
|
||||
[pbr::OriginalName("IMPORT_FOO")] ImportFoo = 7,
|
||||
[pbr::OriginalName("IMPORT_BAR")] ImportBar = 8,
|
||||
[pbr::OriginalName("IMPORT_BAZ")] ImportBaz = 9,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To use an enum in a map, it must has the first value as 0.
|
||||
/// </summary>
|
||||
public enum ImportEnumForMap {
|
||||
[pbr::OriginalName("UNKNOWN")] Unknown = 0,
|
||||
[pbr::OriginalName("FOO")] Foo = 1,
|
||||
[pbr::OriginalName("BAR")] Bar = 2,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Messages
|
||||
public sealed partial class ImportMessage : pb::IMessage<ImportMessage> {
|
||||
private static readonly pb::MessageParser<ImportMessage> _parser = new pb::MessageParser<ImportMessage>(() => new ImportMessage());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<ImportMessage> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::Google.Protobuf.TestProtos.Proto2.UnittestImportReflection.Descriptor.MessageTypes[0]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public ImportMessage() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public ImportMessage(ImportMessage other) : this() {
|
||||
_hasBits0 = other._hasBits0;
|
||||
d_ = other.d_;
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public ImportMessage Clone() {
|
||||
return new ImportMessage(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "d" field.</summary>
|
||||
public const int DFieldNumber = 1;
|
||||
private readonly static int DDefaultValue = 0;
|
||||
|
||||
private int d_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public int D {
|
||||
get { if ((_hasBits0 & 1) != 0) { return d_; } else { return DDefaultValue; } }
|
||||
set {
|
||||
_hasBits0 |= 1;
|
||||
d_ = value;
|
||||
}
|
||||
}
|
||||
/// <summary>Gets whether the "d" field is set</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public bool HasD {
|
||||
get { return (_hasBits0 & 1) != 0; }
|
||||
}
|
||||
/// <summary>Clears the value of the "d" field</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void ClearD() {
|
||||
_hasBits0 &= ~1;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as ImportMessage);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public bool Equals(ImportMessage other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (D != other.D) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (HasD) hash ^= D.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (HasD) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteInt32(D);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (HasD) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(D);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void MergeFrom(ImportMessage other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.HasD) {
|
||||
D = other.D;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
|
||||
break;
|
||||
case 8: {
|
||||
D = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#endregion Designer generated code
|
@ -0,0 +1,188 @@
|
||||
// <auto-generated>
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: unittest_import_public.proto
|
||||
// </auto-generated>
|
||||
#pragma warning disable 1591, 0612, 3021
|
||||
#region Designer generated code
|
||||
|
||||
using pb = global::Google.Protobuf;
|
||||
using pbc = global::Google.Protobuf.Collections;
|
||||
using pbr = global::Google.Protobuf.Reflection;
|
||||
using scg = global::System.Collections.Generic;
|
||||
namespace Google.Protobuf.TestProtos.Proto2 {
|
||||
|
||||
/// <summary>Holder for reflection information generated from unittest_import_public.proto</summary>
|
||||
public static partial class UnittestImportPublicReflection {
|
||||
|
||||
#region Descriptor
|
||||
/// <summary>File descriptor for unittest_import_public.proto</summary>
|
||||
public static pbr::FileDescriptor Descriptor {
|
||||
get { return descriptor; }
|
||||
}
|
||||
private static pbr::FileDescriptor descriptor;
|
||||
|
||||
static UnittestImportPublicReflection() {
|
||||
byte[] descriptorData = global::System.Convert.FromBase64String(
|
||||
string.Concat(
|
||||
"Chx1bml0dGVzdF9pbXBvcnRfcHVibGljLnByb3RvEh9wcm90b2J1Zl91bml0",
|
||||
"dGVzdF9pbXBvcnRfcHJvdG8yIiAKE1B1YmxpY0ltcG9ydE1lc3NhZ2USCQoB",
|
||||
"ZRgBIAEoBUIkqgIhR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3MuUHJvdG8y"));
|
||||
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
|
||||
new pbr::FileDescriptor[] { },
|
||||
new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
|
||||
new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Proto2.PublicImportMessage), global::Google.Protobuf.TestProtos.Proto2.PublicImportMessage.Parser, new[]{ "E" }, null, null, null, null)
|
||||
}));
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
#region Messages
|
||||
public sealed partial class PublicImportMessage : pb::IMessage<PublicImportMessage> {
|
||||
private static readonly pb::MessageParser<PublicImportMessage> _parser = new pb::MessageParser<PublicImportMessage>(() => new PublicImportMessage());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<PublicImportMessage> Parser { get { return _parser; } }
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pbr::MessageDescriptor Descriptor {
|
||||
get { return global::Google.Protobuf.TestProtos.Proto2.UnittestImportPublicReflection.Descriptor.MessageTypes[0]; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
pbr::MessageDescriptor pb::IMessage.Descriptor {
|
||||
get { return Descriptor; }
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public PublicImportMessage() {
|
||||
OnConstruction();
|
||||
}
|
||||
|
||||
partial void OnConstruction();
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public PublicImportMessage(PublicImportMessage other) : this() {
|
||||
_hasBits0 = other._hasBits0;
|
||||
e_ = other.e_;
|
||||
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public PublicImportMessage Clone() {
|
||||
return new PublicImportMessage(this);
|
||||
}
|
||||
|
||||
/// <summary>Field number for the "e" field.</summary>
|
||||
public const int EFieldNumber = 1;
|
||||
private readonly static int EDefaultValue = 0;
|
||||
|
||||
private int e_;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public int E {
|
||||
get { if ((_hasBits0 & 1) != 0) { return e_; } else { return EDefaultValue; } }
|
||||
set {
|
||||
_hasBits0 |= 1;
|
||||
e_ = value;
|
||||
}
|
||||
}
|
||||
/// <summary>Gets whether the "e" field is set</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public bool HasE {
|
||||
get { return (_hasBits0 & 1) != 0; }
|
||||
}
|
||||
/// <summary>Clears the value of the "e" field</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void ClearE() {
|
||||
_hasBits0 &= ~1;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override bool Equals(object other) {
|
||||
return Equals(other as PublicImportMessage);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public bool Equals(PublicImportMessage other) {
|
||||
if (ReferenceEquals(other, null)) {
|
||||
return false;
|
||||
}
|
||||
if (ReferenceEquals(other, this)) {
|
||||
return true;
|
||||
}
|
||||
if (E != other.E) return false;
|
||||
return Equals(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override int GetHashCode() {
|
||||
int hash = 1;
|
||||
if (HasE) hash ^= E.GetHashCode();
|
||||
if (_unknownFields != null) {
|
||||
hash ^= _unknownFields.GetHashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public override string ToString() {
|
||||
return pb::JsonFormatter.ToDiagnosticString(this);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void WriteTo(pb::CodedOutputStream output) {
|
||||
if (HasE) {
|
||||
output.WriteRawTag(8);
|
||||
output.WriteInt32(E);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
_unknownFields.WriteTo(output);
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public int CalculateSize() {
|
||||
int size = 0;
|
||||
if (HasE) {
|
||||
size += 1 + pb::CodedOutputStream.ComputeInt32Size(E);
|
||||
}
|
||||
if (_unknownFields != null) {
|
||||
size += _unknownFields.CalculateSize();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void MergeFrom(PublicImportMessage other) {
|
||||
if (other == null) {
|
||||
return;
|
||||
}
|
||||
if (other.HasE) {
|
||||
E = other.E;
|
||||
}
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
|
||||
}
|
||||
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public void MergeFrom(pb::CodedInputStream input) {
|
||||
uint tag;
|
||||
while ((tag = input.ReadTag()) != 0) {
|
||||
switch(tag) {
|
||||
default:
|
||||
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
|
||||
break;
|
||||
case 8: {
|
||||
E = input.ReadInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#endregion Designer generated code
|
@ -33,12 +33,25 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Google.Protobuf.TestProtos;
|
||||
using Proto2 = Google.Protobuf.TestProtos.Proto2;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
public class UnknownFieldSetTest
|
||||
{
|
||||
public class Data
|
||||
{
|
||||
public static System.Collections.IEnumerable Messages
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return SampleMessages.CreateFullTestAllTypesProto2();
|
||||
yield return SampleMessages.CreateFullTestAllTypes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EmptyUnknownFieldSet()
|
||||
{
|
||||
@ -60,24 +73,23 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMergeCodedInput()
|
||||
[TestCaseSource(typeof(Data), "Messages")]
|
||||
public void TestMergeCodedInput(IMessage message)
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var emptyMessage = new TestEmptyMessage();
|
||||
emptyMessage.MergeFrom(message.ToByteArray());
|
||||
Assert.AreEqual(message.CalculateSize(), emptyMessage.CalculateSize());
|
||||
Assert.AreEqual(message.ToByteArray(), emptyMessage.ToByteArray());
|
||||
|
||||
var newMessage = new TestAllTypes();
|
||||
newMessage.MergeFrom(emptyMessage.ToByteArray());
|
||||
var newMessage = message.Descriptor.Parser.ParseFrom(emptyMessage.ToByteArray());
|
||||
Assert.AreEqual(message, newMessage);
|
||||
Assert.AreEqual(message.CalculateSize(), newMessage.CalculateSize());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMergeMessage()
|
||||
[TestCaseSource(typeof(Data), "Messages")]
|
||||
public void TestMergeMessage(IMessage message)
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var emptyMessage = new TestEmptyMessage();
|
||||
var otherEmptyMessage = new TestEmptyMessage();
|
||||
emptyMessage.MergeFrom(message.ToByteArray());
|
||||
@ -88,9 +100,9 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEquals()
|
||||
[TestCaseSource(typeof(Data), "Messages")]
|
||||
public void TestEquals(IMessage message)
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var emptyMessage = new TestEmptyMessage();
|
||||
var otherEmptyMessage = new TestEmptyMessage();
|
||||
Assert.AreEqual(emptyMessage, otherEmptyMessage);
|
||||
@ -101,9 +113,9 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHashCode()
|
||||
[TestCaseSource(typeof(Data), "Messages")]
|
||||
public void TestHashCode(IMessage message)
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var emptyMessage = new TestEmptyMessage();
|
||||
int hashCode = emptyMessage.GetHashCode();
|
||||
emptyMessage.MergeFrom(message.ToByteArray());
|
||||
@ -111,7 +123,8 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClone()
|
||||
[TestCaseSource(typeof(Data), "Messages")]
|
||||
public void TestClone(IMessage message)
|
||||
{
|
||||
var emptyMessage = new TestEmptyMessage();
|
||||
var otherEmptyMessage = new TestEmptyMessage();
|
||||
@ -119,7 +132,6 @@ namespace Google.Protobuf
|
||||
Assert.AreEqual(emptyMessage.CalculateSize(), otherEmptyMessage.CalculateSize());
|
||||
Assert.AreEqual(emptyMessage.ToByteArray(), otherEmptyMessage.ToByteArray());
|
||||
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
emptyMessage.MergeFrom(message.ToByteArray());
|
||||
otherEmptyMessage = emptyMessage.Clone();
|
||||
Assert.AreEqual(message.CalculateSize(), otherEmptyMessage.CalculateSize());
|
||||
@ -127,9 +139,9 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDiscardUnknownFields()
|
||||
[TestCaseSource(typeof(Data), "Messages")]
|
||||
public void TestDiscardUnknownFields(IMessage message)
|
||||
{
|
||||
var message = SampleMessages.CreateFullTestAllTypes();
|
||||
var goldenEmptyMessage = new TestEmptyMessage();
|
||||
byte[] data = message.ToByteArray();
|
||||
int fullSize = message.CalculateSize();
|
||||
|
Binary file not shown.
@ -148,6 +148,10 @@ namespace Google.Protobuf.Collections
|
||||
{
|
||||
var sizeCalculator = codec.ValueSizeCalculator;
|
||||
int size = count * CodedOutputStream.ComputeRawVarint32Size(tag);
|
||||
if (codec.EndTag != 0)
|
||||
{
|
||||
size += count * CodedOutputStream.ComputeRawVarint32Size(codec.EndTag);
|
||||
}
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
size += sizeCalculator(array[i]);
|
||||
|
@ -89,7 +89,7 @@ namespace Google.Protobuf
|
||||
/// <summary>
|
||||
/// Gets the value of the specified repeated extension, registering it if it doesn't exist
|
||||
/// </summary>
|
||||
public static RepeatedField<TValue> GetOrRegister<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
|
||||
public static RepeatedField<TValue> GetOrInitialize<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget>
|
||||
{
|
||||
IExtensionValue value;
|
||||
if (set == null)
|
||||
@ -115,6 +115,8 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static void Set<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension, TValue value) where TTarget : IExtendableMessage<TTarget>
|
||||
{
|
||||
ProtoPreconditions.CheckNotNullUnconstrained(value, nameof(value));
|
||||
|
||||
IExtensionValue extensionValue;
|
||||
if (set == null)
|
||||
{
|
||||
@ -330,5 +332,10 @@ namespace Google.Protobuf
|
||||
value.WriteTo(stream);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsInitialized()
|
||||
{
|
||||
return ValuesByNumber.Values.All(v => v.IsInitialized());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
using Google.Protobuf.Collections;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
@ -41,11 +42,11 @@ namespace Google.Protobuf
|
||||
void MergeFrom(IExtensionValue value);
|
||||
void WriteTo(CodedOutputStream output);
|
||||
int CalculateSize();
|
||||
bool IsInitialized();
|
||||
}
|
||||
|
||||
internal sealed class ExtensionValue<T> : IExtensionValue
|
||||
{
|
||||
private bool hasValue;
|
||||
private T field;
|
||||
private FieldCodec<T> codec;
|
||||
|
||||
@ -57,10 +58,6 @@ namespace Google.Protobuf
|
||||
|
||||
public int CalculateSize()
|
||||
{
|
||||
if (!hasValue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return codec.CalculateSizeWithTag(field);
|
||||
}
|
||||
|
||||
@ -68,7 +65,6 @@ namespace Google.Protobuf
|
||||
{
|
||||
return new ExtensionValue<T>(codec)
|
||||
{
|
||||
hasValue = hasValue,
|
||||
field = field is IDeepCloneable<T> ? (field as IDeepCloneable<T>).Clone() : field
|
||||
};
|
||||
}
|
||||
@ -80,7 +76,6 @@ namespace Google.Protobuf
|
||||
|
||||
return other is ExtensionValue<T>
|
||||
&& codec.Equals((other as ExtensionValue<T>).codec)
|
||||
&& hasValue.Equals((other as ExtensionValue<T>).hasValue)
|
||||
&& Equals(field, (other as ExtensionValue<T>).field);
|
||||
// we check for equality in the codec since we could have equal field values however the values could be written in different ways
|
||||
}
|
||||
@ -90,7 +85,6 @@ namespace Google.Protobuf
|
||||
unchecked
|
||||
{
|
||||
int hash = 17;
|
||||
hash = hash * 31 + hasValue.GetHashCode();
|
||||
hash = hash * 31 + field.GetHashCode();
|
||||
hash = hash * 31 + codec.GetHashCode();
|
||||
return hash;
|
||||
@ -99,7 +93,6 @@ namespace Google.Protobuf
|
||||
|
||||
public void MergeFrom(CodedInputStream input)
|
||||
{
|
||||
hasValue = true;
|
||||
codec.ValueMerger(input, ref field);
|
||||
}
|
||||
|
||||
@ -107,24 +100,18 @@ namespace Google.Protobuf
|
||||
{
|
||||
if (value is ExtensionValue<T>)
|
||||
{
|
||||
var extensionValue = value as ExtensionValue<T>;
|
||||
if (extensionValue.hasValue)
|
||||
{
|
||||
hasValue |= codec.FieldMerger(ref field, extensionValue.field);
|
||||
}
|
||||
var extensionValue = value as ExtensionValue<T>;
|
||||
codec.FieldMerger(ref field, extensionValue.field);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteTo(CodedOutputStream output)
|
||||
{
|
||||
if (hasValue)
|
||||
output.WriteTag(codec.Tag);
|
||||
codec.ValueWriter(output, field);
|
||||
if (codec.EndTag != 0)
|
||||
{
|
||||
output.WriteTag(codec.Tag);
|
||||
codec.ValueWriter(output, field);
|
||||
if (codec.EndTag != 0)
|
||||
{
|
||||
output.WriteTag(codec.EndTag);
|
||||
}
|
||||
output.WriteTag(codec.EndTag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,11 +119,20 @@ namespace Google.Protobuf
|
||||
|
||||
public void SetValue(T value)
|
||||
{
|
||||
hasValue = true;
|
||||
field = value;
|
||||
}
|
||||
|
||||
public bool HasValue => hasValue;
|
||||
public bool IsInitialized()
|
||||
{
|
||||
if (field is IMessage)
|
||||
{
|
||||
return (field as IMessage).IsInitialized();
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class RepeatedExtensionValue<T> : IExtensionValue
|
||||
@ -203,5 +199,26 @@ namespace Google.Protobuf
|
||||
}
|
||||
|
||||
public RepeatedField<T> GetValue() => field;
|
||||
|
||||
public bool IsInitialized()
|
||||
{
|
||||
for (int i = 0; i < field.Count; i++)
|
||||
{
|
||||
var element = field[i];
|
||||
if (element is IMessage)
|
||||
{
|
||||
if (!(element as IMessage).IsInitialized())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<string> ForString(uint tag, string defaultValue)
|
||||
{
|
||||
return new FieldCodec<string>(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag);
|
||||
return new FieldCodec<string>(input => input.ReadString(), (output, value) => output.WriteString(value), CodedOutputStream.ComputeStringSize, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -229,7 +229,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ByteString> ForBytes(uint tag, ByteString defaultValue)
|
||||
{
|
||||
return new FieldCodec<ByteString>(input => input.ReadBytes(), (output, value) => output.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag);
|
||||
return new FieldCodec<ByteString>(input => input.ReadBytes(), (output, value) => output.WriteBytes(value), CodedOutputStream.ComputeBytesSize, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -240,7 +240,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<bool> ForBool(uint tag, bool defaultValue)
|
||||
{
|
||||
return new FieldCodec<bool>(input => input.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.BoolSize, tag);
|
||||
return new FieldCodec<bool>(input => input.ReadBool(), (output, value) => output.WriteBool(value), CodedOutputStream.BoolSize, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -251,7 +251,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForInt32(uint tag, int defaultValue)
|
||||
{
|
||||
return new FieldCodec<int>(input => input.ReadInt32(), (output, value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag);
|
||||
return new FieldCodec<int>(input => input.ReadInt32(), (output, value) => output.WriteInt32(value), CodedOutputStream.ComputeInt32Size, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -262,7 +262,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForSInt32(uint tag, int defaultValue)
|
||||
{
|
||||
return new FieldCodec<int>(input => input.ReadSInt32(), (output, value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag);
|
||||
return new FieldCodec<int>(input => input.ReadSInt32(), (output, value) => output.WriteSInt32(value), CodedOutputStream.ComputeSInt32Size, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -273,7 +273,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<uint> ForFixed32(uint tag, uint defaultValue)
|
||||
{
|
||||
return new FieldCodec<uint>(input => input.ReadFixed32(), (output, value) => output.WriteFixed32(value), 4, tag);
|
||||
return new FieldCodec<uint>(input => input.ReadFixed32(), (output, value) => output.WriteFixed32(value), 4, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -284,7 +284,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<int> ForSFixed32(uint tag, int defaultValue)
|
||||
{
|
||||
return new FieldCodec<int>(input => input.ReadSFixed32(), (output, value) => output.WriteSFixed32(value), 4, tag);
|
||||
return new FieldCodec<int>(input => input.ReadSFixed32(), (output, value) => output.WriteSFixed32(value), 4, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -295,7 +295,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<uint> ForUInt32(uint tag, uint defaultValue)
|
||||
{
|
||||
return new FieldCodec<uint>(input => input.ReadUInt32(), (output, value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag);
|
||||
return new FieldCodec<uint>(input => input.ReadUInt32(), (output, value) => output.WriteUInt32(value), CodedOutputStream.ComputeUInt32Size, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -306,7 +306,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForInt64(uint tag, long defaultValue)
|
||||
{
|
||||
return new FieldCodec<long>(input => input.ReadInt64(), (output, value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag);
|
||||
return new FieldCodec<long>(input => input.ReadInt64(), (output, value) => output.WriteInt64(value), CodedOutputStream.ComputeInt64Size, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -317,7 +317,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForSInt64(uint tag, long defaultValue)
|
||||
{
|
||||
return new FieldCodec<long>(input => input.ReadSInt64(), (output, value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag);
|
||||
return new FieldCodec<long>(input => input.ReadSInt64(), (output, value) => output.WriteSInt64(value), CodedOutputStream.ComputeSInt64Size, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -328,7 +328,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ulong> ForFixed64(uint tag, ulong defaultValue)
|
||||
{
|
||||
return new FieldCodec<ulong>(input => input.ReadFixed64(), (output, value) => output.WriteFixed64(value), 8, tag);
|
||||
return new FieldCodec<ulong>(input => input.ReadFixed64(), (output, value) => output.WriteFixed64(value), 8, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -339,7 +339,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<long> ForSFixed64(uint tag, long defaultValue)
|
||||
{
|
||||
return new FieldCodec<long>(input => input.ReadSFixed64(), (output, value) => output.WriteSFixed64(value), 8, tag);
|
||||
return new FieldCodec<long>(input => input.ReadSFixed64(), (output, value) => output.WriteSFixed64(value), 8, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -350,7 +350,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<ulong> ForUInt64(uint tag, ulong defaultValue)
|
||||
{
|
||||
return new FieldCodec<ulong>(input => input.ReadUInt64(), (output, value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag);
|
||||
return new FieldCodec<ulong>(input => input.ReadUInt64(), (output, value) => output.WriteUInt64(value), CodedOutputStream.ComputeUInt64Size, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -361,7 +361,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<float> ForFloat(uint tag, float defaultValue)
|
||||
{
|
||||
return new FieldCodec<float>(input => input.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag);
|
||||
return new FieldCodec<float>(input => input.ReadFloat(), (output, value) => output.WriteFloat(value), CodedOutputStream.FloatSize, tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -372,7 +372,7 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<double> ForDouble(uint tag, double defaultValue)
|
||||
{
|
||||
return new FieldCodec<double>(input => input.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag);
|
||||
return new FieldCodec<double>(input => input.ReadDouble(), (output, value) => output.WriteDouble(value), CodedOutputStream.DoubleSize, tag, defaultValue);
|
||||
}
|
||||
|
||||
// Enums are tricky. We can probably use expression trees to build these delegates automatically,
|
||||
@ -391,7 +391,7 @@ namespace Google.Protobuf
|
||||
return new FieldCodec<T>(input => fromInt32(
|
||||
input.ReadEnum()),
|
||||
(output, value) => output.WriteEnum(toInt32(value)),
|
||||
value => CodedOutputStream.ComputeEnumSize(toInt32(value)), tag);
|
||||
value => CodedOutputStream.ComputeEnumSize(toInt32(value)), tag, defaultValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -402,8 +402,15 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for the given tag.</returns>
|
||||
public static FieldCodec<T> ForMessage<T>(uint tag, MessageParser<T> parser) where T : class, IMessage<T>
|
||||
{
|
||||
return new FieldCodec<T>(input => { T message = parser.CreateTemplate(); input.ReadMessage(message); return message; },
|
||||
(output, value) => output.WriteMessage(value), (CodedInputStream i, ref T v) =>
|
||||
return new FieldCodec<T>(
|
||||
input =>
|
||||
{
|
||||
T message = parser.CreateTemplate();
|
||||
input.ReadMessage(message);
|
||||
return message;
|
||||
},
|
||||
(output, value) => output.WriteMessage(value),
|
||||
(CodedInputStream i, ref T v) =>
|
||||
{
|
||||
if (v == null)
|
||||
{
|
||||
@ -427,7 +434,8 @@ namespace Google.Protobuf
|
||||
v.MergeFrom(v2);
|
||||
}
|
||||
return true;
|
||||
}, message => CodedOutputStream.ComputeMessageSize(message), tag);
|
||||
},
|
||||
message => CodedOutputStream.ComputeMessageSize(message), tag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -439,8 +447,16 @@ namespace Google.Protobuf
|
||||
/// <returns>A codec for given tag</returns>
|
||||
public static FieldCodec<T> ForGroup<T>(uint startTag, uint endTag, MessageParser<T> parser) where T : class, IMessage<T>
|
||||
{
|
||||
return new FieldCodec<T>(input => { T message = parser.CreateTemplate(); input.ReadGroup(message); return message; },
|
||||
(output, value) => output.WriteGroup(value), (CodedInputStream i, ref T v) => {
|
||||
return new FieldCodec<T>(
|
||||
input =>
|
||||
{
|
||||
T message = parser.CreateTemplate();
|
||||
input.ReadGroup(message);
|
||||
return message;
|
||||
},
|
||||
(output, value) => output.WriteGroup(value),
|
||||
(CodedInputStream i, ref T v) =>
|
||||
{
|
||||
if (v == null)
|
||||
{
|
||||
v = parser.CreateTemplate();
|
||||
@ -463,7 +479,8 @@ namespace Google.Protobuf
|
||||
v.MergeFrom(v2);
|
||||
}
|
||||
return true;
|
||||
}, message => CodedOutputStream.ComputeGroupSize(message), startTag, endTag);
|
||||
},
|
||||
message => CodedOutputStream.ComputeGroupSize(message), startTag, endTag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -689,7 +706,8 @@ namespace Google.Protobuf
|
||||
Func<CodedInputStream, T> reader,
|
||||
Action<CodedOutputStream, T> writer,
|
||||
int fixedSize,
|
||||
uint tag) : this(reader, writer, _ => fixedSize, tag)
|
||||
uint tag,
|
||||
T defaultValue) : this(reader, writer, _ => fixedSize, tag, defaultValue)
|
||||
{
|
||||
FixedSize = fixedSize;
|
||||
}
|
||||
@ -699,7 +717,7 @@ namespace Google.Protobuf
|
||||
Action<CodedOutputStream, T> writer,
|
||||
Func<T, int> sizeCalculator,
|
||||
uint tag,
|
||||
uint endTag = 0) : this(reader, writer, (CodedInputStream i, ref T v) => v = reader(i), (ref T v, T v2) => { v = v2; return true; }, sizeCalculator, tag, endTag, DefaultDefault)
|
||||
T defaultValue) : this(reader, writer, (CodedInputStream i, ref T v) => v = reader(i), (ref T v, T v2) => { v = v2; return true; }, sizeCalculator, tag, 0, defaultValue)
|
||||
{
|
||||
}
|
||||
|
||||
@ -731,6 +749,7 @@ namespace Google.Protobuf
|
||||
ValueSizeCalculator = sizeCalculator;
|
||||
FixedSize = 0;
|
||||
Tag = tag;
|
||||
EndTag = endTag;
|
||||
DefaultValue = defaultValue;
|
||||
tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
|
||||
if (endTag != 0)
|
||||
|
@ -35,7 +35,8 @@ using Google.Protobuf.Collections;
|
||||
namespace Google.Protobuf
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic interface for a Protocol Buffers message containing one or more extensions, where the type parameter is expected to be the same type as the implementation class
|
||||
/// Generic interface for a Protocol Buffers message containing one or more extensions, where the type parameter is expected to be the same type as the implementation class.
|
||||
/// This interface is experiemental and is subject to change.
|
||||
/// </summary>
|
||||
public interface IExtendableMessage<T> : IMessage<T> where T : IExtendableMessage<T>
|
||||
{
|
||||
@ -46,14 +47,14 @@ namespace Google.Protobuf
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified repeated extension or null if the extension isn't registered in this set.
|
||||
/// For a version of this method that never returns null, use <see cref="IExtendableMessage{T}.GetOrRegisterExtension{TValue}(RepeatedExtension{T, TValue})"/>
|
||||
/// For a version of this method that never returns null, use <see cref="IExtendableMessage{T}.GetOrInitializeExtension{TValue}(RepeatedExtension{T, TValue})"/>
|
||||
/// </summary>
|
||||
RepeatedField<TValue> GetExtension<TValue>(RepeatedExtension<T, TValue> extension);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the specified repeated extension, registering it if it isn't
|
||||
/// <summary>
|
||||
/// Gets the value of the specified repeated extension, registering it if it hasn't already been registered.
|
||||
/// </summary>
|
||||
RepeatedField<TValue> GetOrRegisterExtension<TValue>(RepeatedExtension<T, TValue> extension);
|
||||
RepeatedField<TValue> GetOrInitializeExtension<TValue>(RepeatedExtension<T, TValue> extension);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the specified extension
|
||||
@ -65,13 +66,13 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
bool HasExtension<TValue>(Extension<T, TValue> extension);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the value of the specified extension
|
||||
/// <summary>
|
||||
/// Clears the value of the specified extension
|
||||
/// </summary>
|
||||
void ClearExtension<TValue>(Extension<T, TValue> extension);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the value of the specified repeated extension
|
||||
/// <summary>
|
||||
/// Clears the value of the specified repeated extension
|
||||
/// </summary>
|
||||
void ClearExtension<TValue>(RepeatedExtension<T, TValue> extension);
|
||||
}
|
||||
|
@ -148,11 +148,16 @@ namespace Google.Protobuf
|
||||
/// </summary>
|
||||
public static bool IsInitialized(this IMessage message)
|
||||
{
|
||||
if (message.Descriptor.File.Proto.Syntax != "proto2")
|
||||
if (message.Descriptor.File.Syntax == Syntax.Proto3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!message.Descriptor.IsExtensionsInitialized(message))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return message.Descriptor
|
||||
.Fields
|
||||
.InDeclarationOrder()
|
||||
@ -160,8 +165,16 @@ namespace Google.Protobuf
|
||||
{
|
||||
if (f.IsMap)
|
||||
{
|
||||
var map = (IDictionary)f.Accessor.GetValue(message);
|
||||
return map.Values.OfType<IMessage>().All(IsInitialized);
|
||||
var valueField = f.MessageType.Fields[2];
|
||||
if (valueField.FieldType == FieldType.Message)
|
||||
{
|
||||
var map = (IDictionary)f.Accessor.GetValue(message);
|
||||
return map.Values.Cast<IMessage>().All(IsInitialized);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (f.IsRepeated && f.FieldType == FieldType.Message || f.FieldType == FieldType.Group)
|
||||
{
|
||||
|
@ -254,11 +254,8 @@ namespace Google.Protobuf.Reflection
|
||||
if (extensionValue is ExtensionValue<T>)
|
||||
{
|
||||
ExtensionValue<T> single = extensionValue as ExtensionValue<T>;
|
||||
if (single.HasValue)
|
||||
{
|
||||
value = single.GetValue();
|
||||
return true;
|
||||
}
|
||||
value = single.GetValue();
|
||||
return true;
|
||||
}
|
||||
else if (extensionValue is RepeatedExtensionValue<T>)
|
||||
{
|
||||
@ -279,11 +276,8 @@ namespace Google.Protobuf.Reflection
|
||||
var typeArgs = typeInfo.GenericTypeArguments;
|
||||
if (typeArgs.Length == 1 && typeArgs[0].GetTypeInfo().IsEnum)
|
||||
{
|
||||
if ((bool)typeInfo.GetDeclaredProperty(nameof(ExtensionValue<T>.HasValue)).GetValue(extensionValue))
|
||||
{
|
||||
value = (T)typeInfo.GetDeclaredMethod(nameof(ExtensionValue<T>.GetValue)).Invoke(extensionValue, EmptyParameters);
|
||||
return true;
|
||||
}
|
||||
value = (T)typeInfo.GetDeclaredMethod(nameof(ExtensionValue<T>.GetValue)).Invoke(extensionValue, EmptyParameters);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (type.GetGenericTypeDefinition() == typeof(RepeatedExtensionValue<>))
|
||||
|
@ -12,7 +12,7 @@ using scg = global::System.Collections.Generic;
|
||||
namespace Google.Protobuf.Reflection {
|
||||
|
||||
/// <summary>Holder for reflection information generated from google/protobuf/descriptor.proto</summary>
|
||||
internal static partial class DescriptorReflection {
|
||||
public static partial class DescriptorReflection {
|
||||
|
||||
#region Descriptor
|
||||
/// <summary>File descriptor for google/protobuf/descriptor.proto</summary>
|
||||
@ -193,7 +193,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// The protocol compiler can output a FileDescriptorSet containing the .proto
|
||||
/// files it parses.
|
||||
/// </summary>
|
||||
internal sealed partial class FileDescriptorSet : pb::IMessage<FileDescriptorSet> {
|
||||
public sealed partial class FileDescriptorSet : pb::IMessage<FileDescriptorSet> {
|
||||
private static readonly pb::MessageParser<FileDescriptorSet> _parser = new pb::MessageParser<FileDescriptorSet>(() => new FileDescriptorSet());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -317,7 +317,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes a complete .proto file.
|
||||
/// </summary>
|
||||
internal sealed partial class FileDescriptorProto : pb::IMessage<FileDescriptorProto> {
|
||||
public sealed partial class FileDescriptorProto : pb::IMessage<FileDescriptorProto> {
|
||||
private static readonly pb::MessageParser<FileDescriptorProto> _parser = new pb::MessageParser<FileDescriptorProto>(() => new FileDescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -800,7 +800,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes a message type.
|
||||
/// </summary>
|
||||
internal sealed partial class DescriptorProto : pb::IMessage<DescriptorProto> {
|
||||
public sealed partial class DescriptorProto : pb::IMessage<DescriptorProto> {
|
||||
private static readonly pb::MessageParser<DescriptorProto> _parser = new pb::MessageParser<DescriptorProto>(() => new DescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -1151,7 +1151,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>Container for nested types declared in the DescriptorProto message type.</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static partial class Types {
|
||||
internal sealed partial class ExtensionRange : pb::IMessage<ExtensionRange> {
|
||||
public sealed partial class ExtensionRange : pb::IMessage<ExtensionRange> {
|
||||
private static readonly pb::MessageParser<ExtensionRange> _parser = new pb::MessageParser<ExtensionRange>(() => new ExtensionRange());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -1391,7 +1391,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// fields or extension ranges in the same message. Reserved ranges may
|
||||
/// not overlap.
|
||||
/// </summary>
|
||||
internal sealed partial class ReservedRange : pb::IMessage<ReservedRange> {
|
||||
public sealed partial class ReservedRange : pb::IMessage<ReservedRange> {
|
||||
private static readonly pb::MessageParser<ReservedRange> _parser = new pb::MessageParser<ReservedRange>(() => new ReservedRange());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -1587,10 +1587,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class ExtensionRangeOptions : pb::IExtendableMessage<ExtensionRangeOptions> {
|
||||
public sealed partial class ExtensionRangeOptions : pb::IExtendableMessage<ExtensionRangeOptions> {
|
||||
private static readonly pb::MessageParser<ExtensionRangeOptions> _parser = new pb::MessageParser<ExtensionRangeOptions>(() => new ExtensionRangeOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<ExtensionRangeOptions> _extensions;
|
||||
private pb::ExtensionSet<ExtensionRangeOptions> _Extensions => _extensions;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<ExtensionRangeOptions> Parser { get { return _parser; } }
|
||||
|
||||
@ -1732,8 +1733,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<ExtensionRangeOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<ExtensionRangeOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<ExtensionRangeOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<ExtensionRangeOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -1753,7 +1754,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes a field within a message.
|
||||
/// </summary>
|
||||
internal sealed partial class FieldDescriptorProto : pb::IMessage<FieldDescriptorProto> {
|
||||
public sealed partial class FieldDescriptorProto : pb::IMessage<FieldDescriptorProto> {
|
||||
private static readonly pb::MessageParser<FieldDescriptorProto> _parser = new pb::MessageParser<FieldDescriptorProto>(() => new FieldDescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -2298,7 +2299,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>Container for nested types declared in the FieldDescriptorProto message type.</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static partial class Types {
|
||||
internal enum Type {
|
||||
public enum Type {
|
||||
/// <summary>
|
||||
/// 0 is reserved for errors.
|
||||
/// Order is weird for historical reasons.
|
||||
@ -2349,7 +2350,7 @@ namespace Google.Protobuf.Reflection {
|
||||
[pbr::OriginalName("TYPE_SINT64")] Sint64 = 18,
|
||||
}
|
||||
|
||||
internal enum Label {
|
||||
public enum Label {
|
||||
/// <summary>
|
||||
/// 0 is reserved for errors
|
||||
/// </summary>
|
||||
@ -2366,7 +2367,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes a oneof.
|
||||
/// </summary>
|
||||
internal sealed partial class OneofDescriptorProto : pb::IMessage<OneofDescriptorProto> {
|
||||
public sealed partial class OneofDescriptorProto : pb::IMessage<OneofDescriptorProto> {
|
||||
private static readonly pb::MessageParser<OneofDescriptorProto> _parser = new pb::MessageParser<OneofDescriptorProto>(() => new OneofDescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -2554,7 +2555,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes an enum type.
|
||||
/// </summary>
|
||||
internal sealed partial class EnumDescriptorProto : pb::IMessage<EnumDescriptorProto> {
|
||||
public sealed partial class EnumDescriptorProto : pb::IMessage<EnumDescriptorProto> {
|
||||
private static readonly pb::MessageParser<EnumDescriptorProto> _parser = new pb::MessageParser<EnumDescriptorProto>(() => new EnumDescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -2818,7 +2819,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// is inclusive such that it can appropriately represent the entire int32
|
||||
/// domain.
|
||||
/// </summary>
|
||||
internal sealed partial class EnumReservedRange : pb::IMessage<EnumReservedRange> {
|
||||
public sealed partial class EnumReservedRange : pb::IMessage<EnumReservedRange> {
|
||||
private static readonly pb::MessageParser<EnumReservedRange> _parser = new pb::MessageParser<EnumReservedRange>(() => new EnumReservedRange());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -3017,7 +3018,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes a value within an enum.
|
||||
/// </summary>
|
||||
internal sealed partial class EnumValueDescriptorProto : pb::IMessage<EnumValueDescriptorProto> {
|
||||
public sealed partial class EnumValueDescriptorProto : pb::IMessage<EnumValueDescriptorProto> {
|
||||
private static readonly pb::MessageParser<EnumValueDescriptorProto> _parser = new pb::MessageParser<EnumValueDescriptorProto>(() => new EnumValueDescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -3248,7 +3249,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes a service.
|
||||
/// </summary>
|
||||
internal sealed partial class ServiceDescriptorProto : pb::IMessage<ServiceDescriptorProto> {
|
||||
public sealed partial class ServiceDescriptorProto : pb::IMessage<ServiceDescriptorProto> {
|
||||
private static readonly pb::MessageParser<ServiceDescriptorProto> _parser = new pb::MessageParser<ServiceDescriptorProto>(() => new ServiceDescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -3456,7 +3457,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Describes a method of a service.
|
||||
/// </summary>
|
||||
internal sealed partial class MethodDescriptorProto : pb::IMessage<MethodDescriptorProto> {
|
||||
public sealed partial class MethodDescriptorProto : pb::IMessage<MethodDescriptorProto> {
|
||||
private static readonly pb::MessageParser<MethodDescriptorProto> _parser = new pb::MessageParser<MethodDescriptorProto>(() => new MethodDescriptorProto());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -3815,10 +3816,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class FileOptions : pb::IExtendableMessage<FileOptions> {
|
||||
public sealed partial class FileOptions : pb::IExtendableMessage<FileOptions> {
|
||||
private static readonly pb::MessageParser<FileOptions> _parser = new pb::MessageParser<FileOptions>(() => new FileOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<FileOptions> _extensions;
|
||||
private pb::ExtensionSet<FileOptions> _Extensions => _extensions;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<FileOptions> Parser { get { return _parser; } }
|
||||
@ -4869,8 +4871,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<FileOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<FileOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<FileOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<FileOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -4892,7 +4894,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>
|
||||
/// Generated classes can be optimized for speed or code size.
|
||||
/// </summary>
|
||||
internal enum OptimizeMode {
|
||||
public enum OptimizeMode {
|
||||
/// <summary>
|
||||
/// Generate complete code for parsing, serialization,
|
||||
/// </summary>
|
||||
@ -4912,10 +4914,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class MessageOptions : pb::IExtendableMessage<MessageOptions> {
|
||||
public sealed partial class MessageOptions : pb::IExtendableMessage<MessageOptions> {
|
||||
private static readonly pb::MessageParser<MessageOptions> _parser = new pb::MessageParser<MessageOptions>(() => new MessageOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<MessageOptions> _extensions;
|
||||
private pb::ExtensionSet<MessageOptions> _Extensions => _extensions;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<MessageOptions> Parser { get { return _parser; } }
|
||||
@ -5277,8 +5280,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<MessageOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<MessageOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<MessageOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<MessageOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -5295,10 +5298,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class FieldOptions : pb::IExtendableMessage<FieldOptions> {
|
||||
public sealed partial class FieldOptions : pb::IExtendableMessage<FieldOptions> {
|
||||
private static readonly pb::MessageParser<FieldOptions> _parser = new pb::MessageParser<FieldOptions>(() => new FieldOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<FieldOptions> _extensions;
|
||||
private pb::ExtensionSet<FieldOptions> _Extensions => _extensions;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<FieldOptions> Parser { get { return _parser; } }
|
||||
@ -5752,8 +5756,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<FieldOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<FieldOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<FieldOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<FieldOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -5772,7 +5776,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>Container for nested types declared in the FieldOptions message type.</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static partial class Types {
|
||||
internal enum CType {
|
||||
public enum CType {
|
||||
/// <summary>
|
||||
/// Default mode.
|
||||
/// </summary>
|
||||
@ -5781,7 +5785,7 @@ namespace Google.Protobuf.Reflection {
|
||||
[pbr::OriginalName("STRING_PIECE")] StringPiece = 2,
|
||||
}
|
||||
|
||||
internal enum JSType {
|
||||
public enum JSType {
|
||||
/// <summary>
|
||||
/// Use the default type.
|
||||
/// </summary>
|
||||
@ -5801,10 +5805,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class OneofOptions : pb::IExtendableMessage<OneofOptions> {
|
||||
public sealed partial class OneofOptions : pb::IExtendableMessage<OneofOptions> {
|
||||
private static readonly pb::MessageParser<OneofOptions> _parser = new pb::MessageParser<OneofOptions>(() => new OneofOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<OneofOptions> _extensions;
|
||||
private pb::ExtensionSet<OneofOptions> _Extensions => _extensions;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<OneofOptions> Parser { get { return _parser; } }
|
||||
|
||||
@ -5946,8 +5951,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<OneofOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<OneofOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<OneofOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<OneofOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -5964,10 +5969,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class EnumOptions : pb::IExtendableMessage<EnumOptions> {
|
||||
public sealed partial class EnumOptions : pb::IExtendableMessage<EnumOptions> {
|
||||
private static readonly pb::MessageParser<EnumOptions> _parser = new pb::MessageParser<EnumOptions>(() => new EnumOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<EnumOptions> _extensions;
|
||||
private pb::ExtensionSet<EnumOptions> _Extensions => _extensions;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<EnumOptions> Parser { get { return _parser; } }
|
||||
@ -6203,8 +6209,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<EnumOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<EnumOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<EnumOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<EnumOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -6221,10 +6227,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class EnumValueOptions : pb::IExtendableMessage<EnumValueOptions> {
|
||||
public sealed partial class EnumValueOptions : pb::IExtendableMessage<EnumValueOptions> {
|
||||
private static readonly pb::MessageParser<EnumValueOptions> _parser = new pb::MessageParser<EnumValueOptions>(() => new EnumValueOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<EnumValueOptions> _extensions;
|
||||
private pb::ExtensionSet<EnumValueOptions> _Extensions => _extensions;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<EnumValueOptions> Parser { get { return _parser; } }
|
||||
@ -6415,8 +6422,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<EnumValueOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<EnumValueOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<EnumValueOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<EnumValueOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -6433,10 +6440,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class ServiceOptions : pb::IExtendableMessage<ServiceOptions> {
|
||||
public sealed partial class ServiceOptions : pb::IExtendableMessage<ServiceOptions> {
|
||||
private static readonly pb::MessageParser<ServiceOptions> _parser = new pb::MessageParser<ServiceOptions>(() => new ServiceOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<ServiceOptions> _extensions;
|
||||
private pb::ExtensionSet<ServiceOptions> _Extensions => _extensions;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<ServiceOptions> Parser { get { return _parser; } }
|
||||
@ -6627,8 +6635,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<ServiceOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<ServiceOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<ServiceOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<ServiceOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -6645,10 +6653,11 @@ namespace Google.Protobuf.Reflection {
|
||||
|
||||
}
|
||||
|
||||
internal sealed partial class MethodOptions : pb::IExtendableMessage<MethodOptions> {
|
||||
public sealed partial class MethodOptions : pb::IExtendableMessage<MethodOptions> {
|
||||
private static readonly pb::MessageParser<MethodOptions> _parser = new pb::MessageParser<MethodOptions>(() => new MethodOptions());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
internal pb::ExtensionSet<MethodOptions> _extensions;
|
||||
private pb::ExtensionSet<MethodOptions> _Extensions => _extensions;
|
||||
private int _hasBits0;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static pb::MessageParser<MethodOptions> Parser { get { return _parser; } }
|
||||
@ -6880,8 +6889,8 @@ namespace Google.Protobuf.Reflection {
|
||||
public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<MethodOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.Get(ref _extensions, extension);
|
||||
}
|
||||
public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<MethodOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);
|
||||
public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<MethodOptions, TValue> extension) {
|
||||
return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);
|
||||
}
|
||||
public void SetExtension<TValue>(pb::Extension<MethodOptions, TValue> extension, TValue value) {
|
||||
pb::ExtensionSet.Set(ref _extensions, extension, value);
|
||||
@ -6905,7 +6914,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// or neither? HTTP based RPC implementation may choose GET verb for safe
|
||||
/// methods, and PUT verb for idempotent methods instead of the default POST.
|
||||
/// </summary>
|
||||
internal enum IdempotencyLevel {
|
||||
public enum IdempotencyLevel {
|
||||
[pbr::OriginalName("IDEMPOTENCY_UNKNOWN")] IdempotencyUnknown = 0,
|
||||
/// <summary>
|
||||
/// implies idempotent
|
||||
@ -6930,7 +6939,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
|
||||
/// in them.
|
||||
/// </summary>
|
||||
internal sealed partial class UninterpretedOption : pb::IMessage<UninterpretedOption> {
|
||||
public sealed partial class UninterpretedOption : pb::IMessage<UninterpretedOption> {
|
||||
private static readonly pb::MessageParser<UninterpretedOption> _parser = new pb::MessageParser<UninterpretedOption>(() => new UninterpretedOption());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -7309,7 +7318,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
|
||||
/// "foo.(bar.baz).qux".
|
||||
/// </summary>
|
||||
internal sealed partial class NamePart : pb::IMessage<NamePart> {
|
||||
public sealed partial class NamePart : pb::IMessage<NamePart> {
|
||||
private static readonly pb::MessageParser<NamePart> _parser = new pb::MessageParser<NamePart>(() => new NamePart());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
@ -7502,7 +7511,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// Encapsulates information about the original source file from which a
|
||||
/// FileDescriptorProto was generated.
|
||||
/// </summary>
|
||||
internal sealed partial class SourceCodeInfo : pb::IMessage<SourceCodeInfo> {
|
||||
public sealed partial class SourceCodeInfo : pb::IMessage<SourceCodeInfo> {
|
||||
private static readonly pb::MessageParser<SourceCodeInfo> _parser = new pb::MessageParser<SourceCodeInfo>(() => new SourceCodeInfo());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -7670,7 +7679,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>Container for nested types declared in the SourceCodeInfo message type.</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static partial class Types {
|
||||
internal sealed partial class Location : pb::IMessage<Location> {
|
||||
public sealed partial class Location : pb::IMessage<Location> {
|
||||
private static readonly pb::MessageParser<Location> _parser = new pb::MessageParser<Location>(() => new Location());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -8004,7 +8013,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// file. A GeneratedCodeInfo message is associated with only one generated
|
||||
/// source file, but may contain references to different source .proto files.
|
||||
/// </summary>
|
||||
internal sealed partial class GeneratedCodeInfo : pb::IMessage<GeneratedCodeInfo> {
|
||||
public sealed partial class GeneratedCodeInfo : pb::IMessage<GeneratedCodeInfo> {
|
||||
private static readonly pb::MessageParser<GeneratedCodeInfo> _parser = new pb::MessageParser<GeneratedCodeInfo>(() => new GeneratedCodeInfo());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
@ -8131,7 +8140,7 @@ namespace Google.Protobuf.Reflection {
|
||||
/// <summary>Container for nested types declared in the GeneratedCodeInfo message type.</summary>
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
|
||||
public static partial class Types {
|
||||
internal sealed partial class Annotation : pb::IMessage<Annotation> {
|
||||
public sealed partial class Annotation : pb::IMessage<Annotation> {
|
||||
private static readonly pb::MessageParser<Annotation> _parser = new pb::MessageParser<Annotation>(() => new Annotation());
|
||||
private pb::UnknownFieldSet _unknownFields;
|
||||
private int _hasBits0;
|
||||
|
@ -128,17 +128,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this enum.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<EnumOptions, T> extension)
|
||||
{
|
||||
var value = Proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -148,6 +147,5 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return Proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -73,17 +73,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this enum value.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<EnumValueOptions, T> extension)
|
||||
{
|
||||
var value = Proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -93,7 +92,6 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return Proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// A collection to simplify retrieving the descriptors of extensions in a descriptor for a message
|
||||
/// </summary>
|
||||
public class ExtensionCollection
|
||||
public sealed class ExtensionCollection
|
||||
{
|
||||
private IDictionary<MessageDescriptor, IList<FieldDescriptor>> extensionsByTypeInDeclarationOrder;
|
||||
private IDictionary<MessageDescriptor, IList<FieldDescriptor>> extensionsByTypeInNumberOrder;
|
||||
|
@ -66,7 +66,10 @@ namespace Google.Protobuf.Reflection
|
||||
|
||||
internal FieldDescriptorProto Proto { get; }
|
||||
|
||||
internal Extension Extension { get; }
|
||||
/// <summary>
|
||||
/// An extension identifier for this field, or <c>null</c> if this field isn't an extension.
|
||||
/// </summary>
|
||||
public Extension Extension { get; }
|
||||
|
||||
internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,
|
||||
MessageDescriptor parent, int index, string propertyName, Extension extension)
|
||||
@ -201,7 +204,25 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field is a packed, repeated field; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsPacked => File.Proto.Syntax == "proto2" ? Proto.Options?.Packed ?? false : !Proto.Options.HasPacked || Proto.Options.Packed;
|
||||
public bool IsPacked
|
||||
{
|
||||
get
|
||||
{
|
||||
if (File.Syntax != Syntax.Proto3)
|
||||
{
|
||||
return Proto.Options?.Packed ?? false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return !Proto.Options.HasPacked || Proto.Options.Packed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns <c>true</c> if this field extends another message type; <c>false</c> otherwise.
|
||||
/// </summary>
|
||||
public bool IsExtension => Proto.HasExtendee;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the type of the field.
|
||||
@ -277,17 +298,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this field.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<FieldOptions, T> extension)
|
||||
{
|
||||
var value = Proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -297,7 +317,6 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return Proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Look up and cross-link all field types etc.
|
||||
@ -378,6 +397,11 @@ namespace Google.Protobuf.Reflection
|
||||
|
||||
private IFieldAccessor CreateAccessor()
|
||||
{
|
||||
if (Extension != null)
|
||||
{
|
||||
return new ExtensionAccessor(this);
|
||||
}
|
||||
|
||||
// If we're given no property name, that's because we really don't want an accessor.
|
||||
// This could be because it's a map message, or it could be that we're loading a FileDescriptor dynamically.
|
||||
// TODO: Support dynamic messages.
|
||||
@ -386,10 +410,6 @@ namespace Google.Protobuf.Reflection
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Extension != null)
|
||||
{
|
||||
return new ExtensionAccessor(this);
|
||||
}
|
||||
var property = ContainingType.ClrType.GetProperty(propertyName);
|
||||
if (property == null)
|
||||
{
|
||||
|
@ -42,6 +42,25 @@ using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
|
||||
|
||||
namespace Google.Protobuf.Reflection
|
||||
{
|
||||
/// <summary>
|
||||
/// The syntax of a .proto file
|
||||
/// </summary>
|
||||
public enum Syntax
|
||||
{
|
||||
/// <summary>
|
||||
/// Proto2 syntax
|
||||
/// </summary>
|
||||
Proto2,
|
||||
/// <summary>
|
||||
/// Proto3 syntax
|
||||
/// </summary>
|
||||
Proto3,
|
||||
/// <summary>
|
||||
/// An unknown declared syntax
|
||||
/// </summary>
|
||||
Unknown
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a .proto file, including everything defined within.
|
||||
/// IDescriptor is implemented such that the File property returns this descriptor,
|
||||
@ -87,6 +106,19 @@ namespace Google.Protobuf.Reflection
|
||||
Extensions = new ExtensionCollection(this, generatedCodeInfo?.Extensions);
|
||||
|
||||
declarations = new Lazy<Dictionary<IDescriptor, DescriptorDeclaration>>(CreateDeclarationMap, LazyThreadSafetyMode.ExecutionAndPublication);
|
||||
|
||||
if (!proto.HasSyntax || proto.Syntax == "proto2")
|
||||
{
|
||||
Syntax = Syntax.Proto2;
|
||||
}
|
||||
else if (proto.Syntax == "proto3")
|
||||
{
|
||||
Syntax = Syntax.Proto3;
|
||||
}
|
||||
else
|
||||
{
|
||||
Syntax = Syntax.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<IDescriptor, DescriptorDeclaration> CreateDeclarationMap()
|
||||
@ -217,6 +249,11 @@ namespace Google.Protobuf.Reflection
|
||||
/// </value>
|
||||
internal FileDescriptorProto Proto { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The syntax of the file
|
||||
/// </summary>
|
||||
public Syntax Syntax { get; }
|
||||
|
||||
/// <value>
|
||||
/// The file name.
|
||||
/// </value>
|
||||
@ -504,17 +541,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this file.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<FileOptions, T> extension)
|
||||
{
|
||||
var value = Proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -524,7 +560,6 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return Proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Performs initialization for the given generic type argument.
|
||||
|
@ -51,11 +51,6 @@ namespace Google.Protobuf.Reflection
|
||||
/// </summary>
|
||||
void Clear(IMessage message);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the field in the specified message is set. For proto3 fields, this throws an <see cref="InvalidOperationException"/>
|
||||
/// </summary>
|
||||
bool HasValue(IMessage message);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the field value. For repeated values, this will be an
|
||||
/// <see cref="IList"/> implementation. For map values, this will be an
|
||||
@ -63,6 +58,11 @@ namespace Google.Protobuf.Reflection
|
||||
/// </summary>
|
||||
object GetValue(IMessage message);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the field in the specified message is set. For proto3 fields, this throws an <see cref="InvalidOperationException"/>
|
||||
/// </summary>
|
||||
bool HasValue(IMessage message);
|
||||
|
||||
/// <summary>
|
||||
/// Mutator for single "simple" fields only.
|
||||
/// </summary>
|
||||
|
@ -34,6 +34,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
#if NET35
|
||||
// Needed for ReadOnlyDictionary, which does not exist in .NET 3.5
|
||||
using Google.Protobuf.Collections;
|
||||
@ -63,6 +64,7 @@ namespace Google.Protobuf.Reflection
|
||||
private readonly IList<FieldDescriptor> fieldsInDeclarationOrder;
|
||||
private readonly IList<FieldDescriptor> fieldsInNumberOrder;
|
||||
private readonly IDictionary<string, FieldDescriptor> jsonFieldMap;
|
||||
private Func<IMessage, bool> extensionSetIsInitialized;
|
||||
|
||||
internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, GeneratedClrTypeInfo generatedCodeInfo)
|
||||
: base(file, file.ComputeFullName(parent, proto.Name), typeIndex)
|
||||
@ -134,6 +136,21 @@ namespace Google.Protobuf.Reflection
|
||||
|
||||
internal DescriptorProto Proto { get; }
|
||||
|
||||
internal bool IsExtensionsInitialized(IMessage message)
|
||||
{
|
||||
if (Proto.ExtensionRange.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (extensionSetIsInitialized == null)
|
||||
{
|
||||
extensionSetIsInitialized = ReflectionUtil.CreateIsInitializedCaller(ClrType);
|
||||
}
|
||||
|
||||
return extensionSetIsInitialized(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The CLR type used to represent message instances from this descriptor.
|
||||
/// </summary>
|
||||
@ -243,17 +260,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this message.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<MessageOptions, T> extension)
|
||||
{
|
||||
var value = Proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -263,7 +279,6 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return Proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Looks up and cross-links all fields and nested types.
|
||||
|
@ -73,17 +73,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this method.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<MethodOptions, T> extension)
|
||||
{
|
||||
var value = Proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -93,7 +92,6 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return Proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
|
||||
internal MethodDescriptor(MethodDescriptorProto proto, FileDescriptor file,
|
||||
ServiceDescriptor parent, int index)
|
||||
|
@ -105,17 +105,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this oneof.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<OneofOptions, T> extension)
|
||||
{
|
||||
var value = proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -125,7 +124,6 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
|
||||
internal void CrossLink()
|
||||
{
|
||||
|
@ -115,12 +115,15 @@ namespace Google.Protobuf.Reflection
|
||||
internal static Func<IMessage, bool> CreateFuncIMessageBool(MethodInfo method) =>
|
||||
GetReflectionHelper(method.DeclaringType, method.ReturnType).CreateFuncIMessageBool(method);
|
||||
|
||||
internal static Func<IMessage, bool> CreateIsInitializedCaller(Type msg) =>
|
||||
((IExtensionSetReflector)Activator.CreateInstance(typeof(ExtensionSetReflector<>).MakeGenericType(msg))).CreateIsInitializedCaller();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a delegate which will execute the given method after casting the first argument to
|
||||
/// the type that declares the method, and the second argument to the first parameter type of the method.
|
||||
/// </summary>
|
||||
internal static IExtensionReflectionHelper CreateExtensionHelper(Extension extension) =>
|
||||
(IExtensionReflectionHelper)Activator.CreateInstance(typeof(ExtensionReflectionHelper<,>).MakeGenericType(extension.TargetType, extension.GetType().GenericTypeArguments[1]));
|
||||
(IExtensionReflectionHelper)Activator.CreateInstance(typeof(ExtensionReflectionHelper<,>).MakeGenericType(extension.TargetType, extension.GetType().GenericTypeArguments[1]), extension);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a reflection helper for the given type arguments. Currently these are created on demand
|
||||
@ -150,6 +153,11 @@ namespace Google.Protobuf.Reflection
|
||||
void ClearExtension(IMessage message);
|
||||
}
|
||||
|
||||
private interface IExtensionSetReflector
|
||||
{
|
||||
Func<IMessage, bool> CreateIsInitializedCaller();
|
||||
}
|
||||
|
||||
private class ReflectionHelper<T1, T2> : IReflectionHelper
|
||||
{
|
||||
|
||||
@ -222,7 +230,7 @@ namespace Google.Protobuf.Reflection
|
||||
}
|
||||
else if (extension is RepeatedExtension<T1, T3>)
|
||||
{
|
||||
return extensionMessage.GetExtension(extension as RepeatedExtension<T1, T3>);
|
||||
return extensionMessage.GetOrInitializeExtension(extension as RepeatedExtension<T1, T3>);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -300,6 +308,28 @@ namespace Google.Protobuf.Reflection
|
||||
}
|
||||
}
|
||||
|
||||
private class ExtensionSetReflector<T1> : IExtensionSetReflector where T1 : IExtendableMessage<T1>
|
||||
{
|
||||
public Func<IMessage, bool> CreateIsInitializedCaller()
|
||||
{
|
||||
var prop = typeof(T1).GetTypeInfo().GetDeclaredProperty("_Extensions");
|
||||
#if NET35
|
||||
var getFunc = (Func<T1, ExtensionSet<T1>>)prop.GetGetMethod(true).CreateDelegate(typeof(Func<T1, ExtensionSet<T1>>));
|
||||
#else
|
||||
var getFunc = (Func<T1, ExtensionSet<T1>>)prop.GetMethod.CreateDelegate(typeof(Func<T1, ExtensionSet<T1>>));
|
||||
#endif
|
||||
var initializedFunc = (Func<ExtensionSet<T1>, bool>)
|
||||
typeof(ExtensionSet<T1>)
|
||||
.GetTypeInfo()
|
||||
.GetDeclaredMethod("IsInitialized")
|
||||
.CreateDelegate(typeof(Func<ExtensionSet<T1>, bool>));
|
||||
return (m) => {
|
||||
var set = getFunc((T1)m);
|
||||
return set == null || initializedFunc(set);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Runtime compatibility checking code - see ReflectionHelper<T1, T2>.CreateFuncIMessageInt32 for
|
||||
// details about why we're doing this.
|
||||
|
||||
|
@ -94,17 +94,16 @@ namespace Google.Protobuf.Reflection
|
||||
/// <summary>
|
||||
/// The (possibly empty) set of custom options for this service.
|
||||
/// </summary>
|
||||
//[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
[Obsolete("CustomOptions are obsolete. Use GetOption")]
|
||||
public CustomOptions CustomOptions => new CustomOptions(Proto.Options._extensions?.ValuesByNumber);
|
||||
|
||||
/* // uncomment this in the full proto2 support PR
|
||||
/// <summary>
|
||||
/// Gets a single value enum option for this descriptor
|
||||
/// </summary>
|
||||
public T GetOption<T>(Extension<ServiceOptions, T> extension)
|
||||
{
|
||||
var value = Proto.Options.GetExtension(extension);
|
||||
return value is IDeepCloneable<T> clonable ? clonable.Clone() : value;
|
||||
return value is IDeepCloneable<T> ? (value as IDeepCloneable<T>).Clone() : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -114,7 +113,6 @@ namespace Google.Protobuf.Reflection
|
||||
{
|
||||
return Proto.Options.GetExtension(extension).Clone();
|
||||
}
|
||||
*/
|
||||
|
||||
internal void CrossLink()
|
||||
{
|
||||
|
@ -57,20 +57,7 @@ namespace Google.Protobuf.Reflection
|
||||
throw new ArgumentException("Not all required properties/methods available");
|
||||
}
|
||||
setValueDelegate = ReflectionUtil.CreateActionIMessageObject(property.GetSetMethod());
|
||||
if (descriptor.File.Proto.Syntax == "proto2")
|
||||
{
|
||||
MethodInfo hasMethod = property.DeclaringType.GetRuntimeProperty("Has" + property.Name).GetMethod;
|
||||
if (hasMethod == null) {
|
||||
throw new ArgumentException("Not all required properties/methods are available");
|
||||
}
|
||||
hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod);
|
||||
MethodInfo clearMethod = property.DeclaringType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes);
|
||||
if (clearMethod == null) {
|
||||
throw new ArgumentException("Not all required properties/methods are available");
|
||||
}
|
||||
clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod);
|
||||
}
|
||||
else
|
||||
if (descriptor.File.Syntax == Syntax.Proto3)
|
||||
{
|
||||
hasDelegate = message => {
|
||||
throw new InvalidOperationException("HasValue is not implemented for proto3 fields");
|
||||
@ -85,6 +72,19 @@ namespace Google.Protobuf.Reflection
|
||||
: Activator.CreateInstance(clrType);
|
||||
clearDelegate = message => SetValue(message, defaultValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
MethodInfo hasMethod = property.DeclaringType.GetRuntimeProperty("Has" + property.Name).GetMethod;
|
||||
if (hasMethod == null) {
|
||||
throw new ArgumentException("Not all required properties/methods are available");
|
||||
}
|
||||
hasDelegate = ReflectionUtil.CreateFuncIMessageBool(hasMethod);
|
||||
MethodInfo clearMethod = property.DeclaringType.GetRuntimeMethod("Clear" + property.Name, ReflectionUtil.EmptyTypes);
|
||||
if (clearMethod == null) {
|
||||
throw new ArgumentException("Not all required properties/methods are available");
|
||||
}
|
||||
clearDelegate = ReflectionUtil.CreateActionIMessage(clearMethod);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clear(IMessage message)
|
||||
|
@ -306,7 +306,7 @@ std::string FieldGeneratorBase::GetStringDefaultValueInternal(const FieldDescrip
|
||||
if (descriptor->default_value_string().empty())
|
||||
return "\"\"";
|
||||
else
|
||||
return "global::System.Encoding.UTF8.GetString(global::System.Convert.FromBase64String(\" +" + StringToBase64(descriptor->default_value_string()) + " +\"))";
|
||||
return "global::System.Text.Encoding.UTF8.GetString(global::System.Convert.FromBase64String(\"" + StringToBase64(descriptor->default_value_string()) + "\"))";
|
||||
}
|
||||
|
||||
std::string FieldGeneratorBase::GetBytesDefaultValueInternal(const FieldDescriptor* descriptor) {
|
||||
|
@ -63,12 +63,6 @@ bool Generator::Generate(
|
||||
std::vector<std::pair<string, string> > options;
|
||||
ParseGeneratorParameter(parameter, &options);
|
||||
|
||||
// We only support proto3 - but we make an exception for descriptor.proto.
|
||||
if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 && !IsDescriptorProto(file)) {
|
||||
*error = "C# code generation only supports proto3 syntax";
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Options cli_options;
|
||||
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
|
@ -284,15 +284,34 @@ std::string GetEnumValueName(const std::string& enum_name, const std::string& en
|
||||
|
||||
uint GetGroupEndTag(const Descriptor* descriptor) {
|
||||
const Descriptor* containing_type = descriptor->containing_type();
|
||||
if (containing_type == NULL) {
|
||||
return 0;
|
||||
}
|
||||
const FieldDescriptor* field = containing_type->FindFieldByName(descriptor->name());
|
||||
if (field != NULL && field->type() == FieldDescriptor::Type::TYPE_GROUP) {
|
||||
return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
|
||||
if (containing_type != NULL) {
|
||||
const FieldDescriptor* field;
|
||||
for (int i = 0; i < containing_type->field_count(); i++) {
|
||||
field = containing_type->field(i);
|
||||
if (field->type() == FieldDescriptor::Type::TYPE_GROUP && field->message_type() == descriptor) {
|
||||
return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < containing_type->extension_count(); i++) {
|
||||
field = containing_type->extension(i);
|
||||
if (field->type() == FieldDescriptor::Type::TYPE_GROUP && field->message_type() == descriptor) {
|
||||
return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
const FileDescriptor* containing_file = descriptor->file();
|
||||
if (containing_file != NULL) {
|
||||
const FieldDescriptor* field;
|
||||
for (int i = 0; i < containing_file->extension_count(); i++) {
|
||||
field = containing_file->extension(i);
|
||||
if (field->type() == FieldDescriptor::Type::TYPE_GROUP && field->message_type() == descriptor) {
|
||||
return internal::WireFormatLite::MakeTag(field->number(), internal::WireFormatLite::WIRETYPE_END_GROUP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
|
||||
|
@ -149,6 +149,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
|
||||
} else {
|
||||
printer->Print(vars, "private pb::ExtensionSet<$class_name$> _extensions;\n");
|
||||
}
|
||||
|
||||
printer->Print(vars, "private pb::ExtensionSet<$class_name$> _Extensions => _extensions;\n"); // a read-only property for fast retrieval of the set in IsInitialized
|
||||
}
|
||||
|
||||
for (int i = 0; i < has_bit_field_count_; i++) {
|
||||
@ -270,8 +272,8 @@ void MessageGenerator::Generate(io::Printer* printer) {
|
||||
"public pbc::RepeatedField<TValue> GetExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> extension) {\n"
|
||||
" return pb::ExtensionSet.Get(ref _extensions, extension);\n"
|
||||
"}\n"
|
||||
"public pbc::RepeatedField<TValue> GetOrRegisterExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> extension) {\n"
|
||||
" return pb::ExtensionSet.GetOrRegister(ref _extensions, extension);\n"
|
||||
"public pbc::RepeatedField<TValue> GetOrInitializeExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> extension) {\n"
|
||||
" return pb::ExtensionSet.GetOrInitialize(ref _extensions, extension);\n"
|
||||
"}\n"
|
||||
"public void SetExtension<TValue>(pb::Extension<$class_name$, TValue> extension, TValue value) {\n"
|
||||
" pb::ExtensionSet.Set(ref _extensions, extension, value);\n"
|
||||
@ -320,7 +322,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
|
||||
"#region Extensions\n"
|
||||
"/// <summary>Container for extensions for other messages declared in the $class_name$ message type.</summary>\n");
|
||||
WriteGeneratedCodeAttributes(printer);
|
||||
printer->Print("internal static partial class Extensions {\n");
|
||||
printer->Print("public static partial class Extensions {\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < descriptor_->extension_count(); i++) {
|
||||
std::unique_ptr<FieldGeneratorBase> generator(
|
||||
@ -625,7 +627,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
|
||||
printer->Indent();
|
||||
if (end_tag_ != 0) {
|
||||
printer->Print(
|
||||
"$end_tag$:\n"
|
||||
"case $end_tag$:\n"
|
||||
" return;\n",
|
||||
"end_tag", StrCat(end_tag_));
|
||||
}
|
||||
@ -681,7 +683,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
|
||||
|
||||
// it's a waste of space to track presence for all values, so we only track them if they're not nullable
|
||||
int MessageGenerator::GetPresenceIndex(const FieldDescriptor* descriptor) {
|
||||
if (IsNullable(descriptor) || !IsProto2(descriptor_->file())) {
|
||||
if (IsNullable(descriptor) || !IsProto2(descriptor->file()) || descriptor->is_extension()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) {
|
||||
if (file_->extension_count() > 0) {
|
||||
printer->Print(
|
||||
"/// <summary>Holder for extension identifiers generated from the top level of $file_name$</summary>\n"
|
||||
"internal static partial class $class_name$ {\n",
|
||||
"$access_level$ static partial class $class_name$ {\n",
|
||||
"access_level", class_access_level(),
|
||||
"class_name", extensionClassname_,
|
||||
"file_name", file_->name());
|
||||
|
@ -59,7 +59,7 @@ void SourceGeneratorBase::WriteGeneratedCodeAttributes(io::Printer* printer) {
|
||||
}
|
||||
|
||||
std::string SourceGeneratorBase::class_access_level() {
|
||||
return (IsDescriptorProto(descriptor_) || this->options()->internal_access) ? "internal" : "public";
|
||||
return this->options()->internal_access ? "internal" : "public";
|
||||
}
|
||||
|
||||
const Options* SourceGeneratorBase::options() {
|
||||
|
Loading…
Reference in New Issue
Block a user