aboutsummaryrefslogtreecommitdiff
path: root/csharp/src
diff options
context:
space:
mode:
authorJie Luo <anandolee@gmail.com>2016-05-11 16:07:43 -0700
committerJie Luo <anandolee@gmail.com>2016-05-11 16:07:43 -0700
commite1f588ae3c5efc7e297e1cb76d42f46d0d4eb3ca (patch)
tree903944637fd62784dfc1c844eb5af96bdffe9863 /csharp/src
parentc61207492efa36244ffa16cc5b394e71888e4c0f (diff)
parent71dd9c4a5ed5c0fb3eff12cddd17116432db9faf (diff)
downloadprotobuf-e1f588ae3c5efc7e297e1cb76d42f46d0d4eb3ca.tar.gz
protobuf-e1f588ae3c5efc7e297e1cb76d42f46d0d4eb3ca.tar.bz2
protobuf-e1f588ae3c5efc7e297e1cb76d42f46d0d4eb3ca.zip
Merge pull request #1 from google/beta-3
Beta 3
Diffstat (limited to 'csharp/src')
-rw-r--r--csharp/src/AddressBook/AddPerson.cs6
-rw-r--r--csharp/src/AddressBook/Addressbook.cs47
-rw-r--r--csharp/src/AddressBook/ListPeople.cs6
-rw-r--r--csharp/src/AddressBook/SampleUsage.cs7
-rw-r--r--csharp/src/Google.Protobuf.Conformance/Conformance.cs1528
-rw-r--r--csharp/src/Google.Protobuf.Conformance/Program.cs66
-rw-r--r--csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs76
-rw-r--r--csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs28
-rw-r--r--csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs56
-rw-r--r--csharp/src/Google.Protobuf.Test/FieldCodecTest.cs2
-rw-r--r--csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs110
-rw-r--r--csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj7
-rw-r--r--csharp/src/Google.Protobuf.Test/IssuesTest.cs19
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs205
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonParserTest.cs936
-rw-r--r--csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs408
-rw-r--r--csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs45
-rw-r--r--csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs4
-rw-r--r--csharp/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs94
-rw-r--r--csharp/src/Google.Protobuf.Test/SampleMessages.cs16
-rw-r--r--csharp/src/Google.Protobuf.Test/TestCornerCases.cs4
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs45
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs60
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs24
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs14
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs267
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs332
-rw-r--r--csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs95
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs50
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs38
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs62
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs31
-rw-r--r--csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs88
-rw-r--r--csharp/src/Google.Protobuf.sln6
-rw-r--r--csharp/src/Google.Protobuf/ByteString.cs6
-rw-r--r--csharp/src/Google.Protobuf/CodedInputStream.cs82
-rw-r--r--csharp/src/Google.Protobuf/CodedOutputStream.cs67
-rw-r--r--csharp/src/Google.Protobuf/Collections/MapField.cs76
-rw-r--r--csharp/src/Google.Protobuf/Collections/RepeatedField.cs16
-rw-r--r--csharp/src/Google.Protobuf/FieldCodec.cs167
-rw-r--r--csharp/src/Google.Protobuf/Google.Protobuf.csproj28
-rw-r--r--csharp/src/Google.Protobuf/Google.Protobuf.nuspec53
-rw-r--r--csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs69
-rw-r--r--csharp/src/Google.Protobuf/InvalidJsonException.cs53
-rw-r--r--csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs18
-rw-r--r--csharp/src/Google.Protobuf/JsonFormatter.cs512
-rw-r--r--csharp/src/Google.Protobuf/JsonParser.cs1018
-rw-r--r--csharp/src/Google.Protobuf/JsonToken.cs166
-rw-r--r--csharp/src/Google.Protobuf/JsonTokenizer.cs738
-rw-r--r--csharp/src/Google.Protobuf/MessageExtensions.cs28
-rw-r--r--csharp/src/Google.Protobuf/MessageParser.cs141
-rw-r--r--csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs5
-rw-r--r--csharp/src/Google.Protobuf/ProtoPreconditions.cs (renamed from csharp/src/Google.Protobuf/Preconditions.cs)9
-rw-r--r--csharp/src/Google.Protobuf/Reflection/Descriptor.cs (renamed from csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs)844
-rw-r--r--csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs10
-rw-r--r--csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs161
-rw-r--r--csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs134
-rw-r--r--csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs103
-rw-r--r--csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs66
-rw-r--r--csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs180
-rw-r--r--csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs15
-rw-r--r--csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs58
-rw-r--r--csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs2
-rw-r--r--csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs183
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Any.cs110
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs48
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Api.cs146
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs68
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs131
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs58
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs110
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs123
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs59
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs104
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs73
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs90
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Type.cs329
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs99
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs82
-rw-r--r--csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs42
-rw-r--r--csharp/src/Google.Protobuf/packages.config4
81 files changed, 9267 insertions, 2199 deletions
diff --git a/csharp/src/AddressBook/AddPerson.cs b/csharp/src/AddressBook/AddPerson.cs
index 6eeb9f6e..62d1788d 100644
--- a/csharp/src/AddressBook/AddPerson.cs
+++ b/csharp/src/AddressBook/AddPerson.cs
@@ -73,13 +73,13 @@ namespace Google.Protobuf.Examples.AddressBook
switch (type)
{
case "mobile":
- phoneNumber.Type = Person.Types.PhoneType.MOBILE;
+ phoneNumber.Type = Person.Types.PhoneType.Mobile;
break;
case "home":
- phoneNumber.Type = Person.Types.PhoneType.HOME;
+ phoneNumber.Type = Person.Types.PhoneType.Home;
break;
case "work":
- phoneNumber.Type = Person.Types.PhoneType.WORK;
+ phoneNumber.Type = Person.Types.PhoneType.Work;
break;
default:
output.Write("Unknown phone type. Using default.");
diff --git a/csharp/src/AddressBook/Addressbook.cs b/csharp/src/AddressBook/Addressbook.cs
index a830418a..362e1cb6 100644
--- a/csharp/src/AddressBook/Addressbook.cs
+++ b/csharp/src/AddressBook/Addressbook.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.Examples.AddressBook {
/// <summary>Holder for reflection information generated from addressbook.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Addressbook {
+ public static partial class AddressbookReflection {
#region Descriptor
/// <summary>File descriptor for addressbook.proto</summary>
@@ -20,7 +20,7 @@ namespace Google.Protobuf.Examples.AddressBook {
}
private static pbr::FileDescriptor descriptor;
- static Addressbook() {
+ static AddressbookReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChFhZGRyZXNzYm9vay5wcm90bxIIdHV0b3JpYWwi1QEKBlBlcnNvbhIMCgRu",
@@ -32,24 +32,27 @@ namespace Google.Protobuf.Examples.AddressBook {
"GAEgAygLMhAudHV0b3JpYWwuUGVyc29uQlAKFGNvbS5leGFtcGxlLnR1dG9y",
"aWFsQhFBZGRyZXNzQm9va1Byb3Rvc6oCJEdvb2dsZS5Qcm90b2J1Zi5FeGFt",
"cGxlcy5BZGRyZXNzQm9va2IGcHJvdG8z"));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person), new[]{ "Name", "Id", "Email", "Phones" }, null, new[]{ typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber), new[]{ "Number", "Type" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.AddressBook), new[]{ "People" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person), global::Google.Protobuf.Examples.AddressBook.Person.Parser, new[]{ "Name", "Id", "Email", "Phones" }, null, new[]{ typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber), global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneNumber.Parser, new[]{ "Number", "Type" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Examples.AddressBook.AddressBook), global::Google.Protobuf.Examples.AddressBook.AddressBook.Parser, new[]{ "People" }, null, null, null)
}));
}
#endregion
}
#region Messages
+ /// <summary>
+ /// [START messages]
+ /// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Person : pb::IMessage<Person> {
private static readonly pb::MessageParser<Person> _parser = new pb::MessageParser<Person>(() => new Person());
public static pb::MessageParser<Person> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Examples.AddressBook.Addressbook.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.Examples.AddressBook.AddressbookReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -79,7 +82,7 @@ namespace Google.Protobuf.Examples.AddressBook {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -102,7 +105,7 @@ namespace Google.Protobuf.Examples.AddressBook {
public string Email {
get { return email_; }
set {
- email_ = pb::Preconditions.CheckNotNull(value, "value");
+ email_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -143,7 +146,7 @@ namespace Google.Protobuf.Examples.AddressBook {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -225,9 +228,9 @@ namespace Google.Protobuf.Examples.AddressBook {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class Types {
public enum PhoneType {
- MOBILE = 0,
- HOME = 1,
- WORK = 2,
+ [pbr::OriginalName("MOBILE")] Mobile = 0,
+ [pbr::OriginalName("HOME")] Home = 1,
+ [pbr::OriginalName("WORK")] Work = 2,
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -264,13 +267,13 @@ namespace Google.Protobuf.Examples.AddressBook {
public string Number {
get { return number_; }
set {
- number_ = pb::Preconditions.CheckNotNull(value, "value");
+ number_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "type" field.</summary>
public const int TypeFieldNumber = 2;
- private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE;
+ private global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType type_ = 0;
public global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType Type {
get { return type_; }
set {
@@ -297,12 +300,12 @@ namespace Google.Protobuf.Examples.AddressBook {
public override int GetHashCode() {
int hash = 1;
if (Number.Length != 0) hash ^= Number.GetHashCode();
- if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) hash ^= Type.GetHashCode();
+ if (Type != 0) hash ^= Type.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -310,7 +313,7 @@ namespace Google.Protobuf.Examples.AddressBook {
output.WriteRawTag(10);
output.WriteString(Number);
}
- if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
+ if (Type != 0) {
output.WriteRawTag(16);
output.WriteEnum((int) Type);
}
@@ -321,7 +324,7 @@ namespace Google.Protobuf.Examples.AddressBook {
if (Number.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(Number);
}
- if (Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
+ if (Type != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
}
return size;
@@ -334,7 +337,7 @@ namespace Google.Protobuf.Examples.AddressBook {
if (other.Number.Length != 0) {
Number = other.Number;
}
- if (other.Type != global::Google.Protobuf.Examples.AddressBook.Person.Types.PhoneType.MOBILE) {
+ if (other.Type != 0) {
Type = other.Type;
}
}
@@ -374,7 +377,7 @@ namespace Google.Protobuf.Examples.AddressBook {
public static pb::MessageParser<AddressBook> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Examples.AddressBook.Addressbook.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.Examples.AddressBook.AddressbookReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -426,7 +429,7 @@ namespace Google.Protobuf.Examples.AddressBook {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/AddressBook/ListPeople.cs b/csharp/src/AddressBook/ListPeople.cs
index 3979430f..3758c1bc 100644
--- a/csharp/src/AddressBook/ListPeople.cs
+++ b/csharp/src/AddressBook/ListPeople.cs
@@ -55,13 +55,13 @@ namespace Google.Protobuf.Examples.AddressBook
{
switch (phoneNumber.Type)
{
- case Person.Types.PhoneType.MOBILE:
+ case Person.Types.PhoneType.Mobile:
Console.Write(" Mobile phone #: ");
break;
- case Person.Types.PhoneType.HOME:
+ case Person.Types.PhoneType.Home:
Console.Write(" Home phone #: ");
break;
- case Person.Types.PhoneType.WORK:
+ case Person.Types.PhoneType.Work:
Console.Write(" Work phone #: ");
break;
}
diff --git a/csharp/src/AddressBook/SampleUsage.cs b/csharp/src/AddressBook/SampleUsage.cs
index 936c3bea..aaaedda4 100644
--- a/csharp/src/AddressBook/SampleUsage.cs
+++ b/csharp/src/AddressBook/SampleUsage.cs
@@ -56,8 +56,11 @@ namespace Google.Protobuf.Examples.AddressBook
}
Person copy = Person.Parser.ParseFrom(bytes);
- // A more streamlined approach might look like this:
- bytes = copy.ToByteArray();
+ AddressBook book = new AddressBook
+ {
+ People = { copy }
+ };
+ bytes = book.ToByteArray();
// And read the address book back again
AddressBook restored = AddressBook.Parser.ParseFrom(bytes);
// The message performs a deep-comparison on equality:
diff --git a/csharp/src/Google.Protobuf.Conformance/Conformance.cs b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
index dfd331ae..1674a673 100644
--- a/csharp/src/Google.Protobuf.Conformance/Conformance.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Conformance.cs
@@ -11,7 +11,7 @@ namespace Conformance {
/// <summary>Holder for reflection information generated from conformance.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Conformance {
+ public static partial class ConformanceReflection {
#region Descriptor
/// <summary>File descriptor for conformance.proto</summary>
@@ -20,128 +20,178 @@ namespace Conformance {
}
private static pbr::FileDescriptor descriptor;
- static Conformance() {
+ static ConformanceReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
- "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2UijQEKEkNvbmZvcm1h",
- "bmNlUmVxdWVzdBIaChBwcm90b2J1Zl9wYXlsb2FkGAEgASgMSAASFgoManNv",
- "bl9wYXlsb2FkGAIgASgJSAASOAoXcmVxdWVzdGVkX291dHB1dF9mb3JtYXQY",
- "AyABKA4yFy5jb25mb3JtYW5jZS5XaXJlRm9ybWF0QgkKB3BheWxvYWQilgEK",
- "E0NvbmZvcm1hbmNlUmVzcG9uc2USFQoLcGFyc2VfZXJyb3IYASABKAlIABIX",
- "Cg1ydW50aW1lX2Vycm9yGAIgASgJSAASGgoQcHJvdG9idWZfcGF5bG9hZBgD",
- "IAEoDEgAEhYKDGpzb25fcGF5bG9hZBgEIAEoCUgAEhEKB3NraXBwZWQYBSAB",
- "KAlIAEIICgZyZXN1bHQi6yIKDFRlc3RBbGxUeXBlcxIWCg5vcHRpb25hbF9p",
- "bnQzMhgBIAEoBRIWCg5vcHRpb25hbF9pbnQ2NBgCIAEoAxIXCg9vcHRpb25h",
- "bF91aW50MzIYAyABKA0SFwoPb3B0aW9uYWxfdWludDY0GAQgASgEEhcKD29w",
- "dGlvbmFsX3NpbnQzMhgFIAEoERIXCg9vcHRpb25hbF9zaW50NjQYBiABKBIS",
- "GAoQb3B0aW9uYWxfZml4ZWQzMhgHIAEoBxIYChBvcHRpb25hbF9maXhlZDY0",
- "GAggASgGEhkKEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPEhkKEW9wdGlvbmFs",
- "X3NmaXhlZDY0GAogASgQEhYKDm9wdGlvbmFsX2Zsb2F0GAsgASgCEhcKD29w",
- "dGlvbmFsX2RvdWJsZRgMIAEoARIVCg1vcHRpb25hbF9ib29sGA0gASgIEhcK",
- "D29wdGlvbmFsX3N0cmluZxgOIAEoCRIWCg5vcHRpb25hbF9ieXRlcxgPIAEo",
- "DBJIChdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZRgSIAEoCzInLmNvbmZvcm1h",
- "bmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlEj0KGG9wdGlvbmFsX2Zv",
- "cmVpZ25fbWVzc2FnZRgTIAEoCzIbLmNvbmZvcm1hbmNlLkZvcmVpZ25NZXNz",
- "YWdlEkIKFG9wdGlvbmFsX25lc3RlZF9lbnVtGBUgASgOMiQuY29uZm9ybWFu",
- "Y2UuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0SNwoVb3B0aW9uYWxfZm9yZWln",
- "bl9lbnVtGBYgASgOMhguY29uZm9ybWFuY2UuRm9yZWlnbkVudW0SIQoVb3B0",
- "aW9uYWxfc3RyaW5nX3BpZWNlGBggASgJQgIIAhIZCg1vcHRpb25hbF9jb3Jk",
- "GBkgASgJQgIIARI0ChFyZWN1cnNpdmVfbWVzc2FnZRgbIAEoCzIZLmNvbmZv",
- "cm1hbmNlLlRlc3RBbGxUeXBlcxIWCg5yZXBlYXRlZF9pbnQzMhgfIAMoBRIW",
- "Cg5yZXBlYXRlZF9pbnQ2NBggIAMoAxIXCg9yZXBlYXRlZF91aW50MzIYISAD",
- "KA0SFwoPcmVwZWF0ZWRfdWludDY0GCIgAygEEhcKD3JlcGVhdGVkX3NpbnQz",
- "MhgjIAMoERIXCg9yZXBlYXRlZF9zaW50NjQYJCADKBISGAoQcmVwZWF0ZWRf",
- "Zml4ZWQzMhglIAMoBxIYChByZXBlYXRlZF9maXhlZDY0GCYgAygGEhkKEXJl",
- "cGVhdGVkX3NmaXhlZDMyGCcgAygPEhkKEXJlcGVhdGVkX3NmaXhlZDY0GCgg",
- "AygQEhYKDnJlcGVhdGVkX2Zsb2F0GCkgAygCEhcKD3JlcGVhdGVkX2RvdWJs",
- "ZRgqIAMoARIVCg1yZXBlYXRlZF9ib29sGCsgAygIEhcKD3JlcGVhdGVkX3N0",
- "cmluZxgsIAMoCRIWCg5yZXBlYXRlZF9ieXRlcxgtIAMoDBJIChdyZXBlYXRl",
- "ZF9uZXN0ZWRfbWVzc2FnZRgwIAMoCzInLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
- "eXBlcy5OZXN0ZWRNZXNzYWdlEj0KGHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2Fn",
- "ZRgxIAMoCzIbLmNvbmZvcm1hbmNlLkZvcmVpZ25NZXNzYWdlEkIKFHJlcGVh",
- "dGVkX25lc3RlZF9lbnVtGDMgAygOMiQuY29uZm9ybWFuY2UuVGVzdEFsbFR5",
- "cGVzLk5lc3RlZEVudW0SNwoVcmVwZWF0ZWRfZm9yZWlnbl9lbnVtGDQgAygO",
- "MhguY29uZm9ybWFuY2UuRm9yZWlnbkVudW0SIQoVcmVwZWF0ZWRfc3RyaW5n",
- "X3BpZWNlGDYgAygJQgIIAhIZCg1yZXBlYXRlZF9jb3JkGDcgAygJQgIIARJF",
- "Cg9tYXBfaW50MzJfaW50MzIYOCADKAsyLC5jb25mb3JtYW5jZS5UZXN0QWxs",
- "VHlwZXMuTWFwSW50MzJJbnQzMkVudHJ5EkUKD21hcF9pbnQ2NF9pbnQ2NBg5",
- "IAMoCzIsLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBJbnQ2NEludDY0",
- "RW50cnkSSQoRbWFwX3VpbnQzMl91aW50MzIYOiADKAsyLi5jb25mb3JtYW5j",
- "ZS5UZXN0QWxsVHlwZXMuTWFwVWludDMyVWludDMyRW50cnkSSQoRbWFwX3Vp",
- "bnQ2NF91aW50NjQYOyADKAsyLi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMu",
- "TWFwVWludDY0VWludDY0RW50cnkSSQoRbWFwX3NpbnQzMl9zaW50MzIYPCAD",
- "KAsyLi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU2ludDMyU2ludDMy",
- "RW50cnkSSQoRbWFwX3NpbnQ2NF9zaW50NjQYPSADKAsyLi5jb25mb3JtYW5j",
- "ZS5UZXN0QWxsVHlwZXMuTWFwU2ludDY0U2ludDY0RW50cnkSTQoTbWFwX2Zp",
- "eGVkMzJfZml4ZWQzMhg+IAMoCzIwLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBl",
- "cy5NYXBGaXhlZDMyRml4ZWQzMkVudHJ5Ek0KE21hcF9maXhlZDY0X2ZpeGVk",
- "NjQYPyADKAsyMC5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwRml4ZWQ2",
- "NEZpeGVkNjRFbnRyeRJRChVtYXBfc2ZpeGVkMzJfc2ZpeGVkMzIYQCADKAsy",
- "Mi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU2ZpeGVkMzJTZml4ZWQz",
- "MkVudHJ5ElEKFW1hcF9zZml4ZWQ2NF9zZml4ZWQ2NBhBIAMoCzIyLmNvbmZv",
- "cm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkS",
- "RQoPbWFwX2ludDMyX2Zsb2F0GEIgAygLMiwuY29uZm9ybWFuY2UuVGVzdEFs",
- "bFR5cGVzLk1hcEludDMyRmxvYXRFbnRyeRJHChBtYXBfaW50MzJfZG91Ymxl",
- "GEMgAygLMi0uY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcEludDMyRG91",
- "YmxlRW50cnkSQQoNbWFwX2Jvb2xfYm9vbBhEIAMoCzIqLmNvbmZvcm1hbmNl",
- "LlRlc3RBbGxUeXBlcy5NYXBCb29sQm9vbEVudHJ5EkkKEW1hcF9zdHJpbmdf",
- "c3RyaW5nGEUgAygLMi4uY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcFN0",
- "cmluZ1N0cmluZ0VudHJ5EkcKEG1hcF9zdHJpbmdfYnl0ZXMYRiADKAsyLS5j",
- "b25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU3RyaW5nQnl0ZXNFbnRyeRJY",
- "ChltYXBfc3RyaW5nX25lc3RlZF9tZXNzYWdlGEcgAygLMjUuY29uZm9ybWFu",
- "Y2UuVGVzdEFsbFR5cGVzLk1hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRJa",
- "ChptYXBfc3RyaW5nX2ZvcmVpZ25fbWVzc2FnZRhIIAMoCzI2LmNvbmZvcm1h",
- "bmNlLlRlc3RBbGxUeXBlcy5NYXBTdHJpbmdGb3JlaWduTWVzc2FnZUVudHJ5",
- "ElIKFm1hcF9zdHJpbmdfbmVzdGVkX2VudW0YSSADKAsyMi5jb25mb3JtYW5j",
- "ZS5UZXN0QWxsVHlwZXMuTWFwU3RyaW5nTmVzdGVkRW51bUVudHJ5ElQKF21h",
- "cF9zdHJpbmdfZm9yZWlnbl9lbnVtGEogAygLMjMuY29uZm9ybWFuY2UuVGVz",
- "dEFsbFR5cGVzLk1hcFN0cmluZ0ZvcmVpZ25FbnVtRW50cnkSFgoMb25lb2Zf",
- "dWludDMyGG8gASgNSAASRwoUb25lb2ZfbmVzdGVkX21lc3NhZ2UYcCABKAsy",
- "Jy5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUgAEhYK",
- "DG9uZW9mX3N0cmluZxhxIAEoCUgAEhUKC29uZW9mX2J5dGVzGHIgASgMSAAa",
- "SgoNTmVzdGVkTWVzc2FnZRIJCgFhGAEgASgFEi4KC2NvcmVjdXJzaXZlGAIg",
- "ASgLMhkuY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzGjQKEk1hcEludDMySW50",
- "MzJFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1h",
- "cEludDY0SW50NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6",
- "AjgBGjYKFE1hcFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2",
- "YWx1ZRgCIAEoDToCOAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5",
- "GAEgASgEEg0KBXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJF",
- "bnRyeRILCgNrZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNp",
- "bnQ2NFNpbnQ2NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoC",
- "OAEaOAoWTWFwRml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoF",
- "dmFsdWUYAiABKAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoD",
- "a2V5GAEgASgGEg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNm",
- "aXhlZDMyRW50cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6",
- "ChhNYXBTZml4ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZh",
- "bHVlGAIgASgQOgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEg",
- "ASgFEg0KBXZhbHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5",
- "EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJv",
- "b2xFbnRyeRILCgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1h",
- "cFN0cmluZ1N0cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEo",
- "CToCOAEaNQoTTWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoF",
- "dmFsdWUYAiABKAw6AjgBGmYKG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRy",
- "eRILCgNrZXkYASABKAkSNgoFdmFsdWUYAiABKAsyJy5jb25mb3JtYW5jZS5U",
- "ZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZToCOAEaWwocTWFwU3RyaW5nRm9y",
- "ZWlnbk1lc3NhZ2VFbnRyeRILCgNrZXkYASABKAkSKgoFdmFsdWUYAiABKAsy",
- "Gy5jb25mb3JtYW5jZS5Gb3JlaWduTWVzc2FnZToCOAEaYAoYTWFwU3RyaW5n",
- "TmVzdGVkRW51bUVudHJ5EgsKA2tleRgBIAEoCRIzCgV2YWx1ZRgCIAEoDjIk",
- "LmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtOgI4ARpVChlN",
- "YXBTdHJpbmdGb3JlaWduRW51bUVudHJ5EgsKA2tleRgBIAEoCRInCgV2YWx1",
- "ZRgCIAEoDjIYLmNvbmZvcm1hbmNlLkZvcmVpZ25FbnVtOgI4ASI5CgpOZXN0",
- "ZWRFbnVtEgcKA0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD/////",
- "//////8BQg0KC29uZW9mX2ZpZWxkIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMY",
- "ASABKAUqNQoKV2lyZUZvcm1hdBIPCgtVTlNQRUNJRklFRBAAEgwKCFBST1RP",
- "QlVGEAESCAoESlNPThACKkAKC0ZvcmVpZ25FbnVtEg8KC0ZPUkVJR05fRk9P",
- "EAASDwoLRk9SRUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhACQiEKH2NvbS5n",
- "b29nbGUucHJvdG9idWYuY29uZm9ybWFuY2ViBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.ForeignEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.ConformanceRequest), new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat" }, new[]{ "Payload" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.ConformanceResponse), new[]{ "ParseError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped" }, new[]{ "Result" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.TestAllTypes), new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Conformance.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Conformance.TestAllTypes.Types.NestedMessage), new[]{ "A", "Corecursive" }, null, null, null),
+ "ChFjb25mb3JtYW5jZS5wcm90bxILY29uZm9ybWFuY2UaGWdvb2dsZS9wcm90",
+ "b2J1Zi9hbnkucHJvdG8aHmdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90",
+ "bxogZ29vZ2xlL3Byb3RvYnVmL2ZpZWxkX21hc2sucHJvdG8aHGdvb2dsZS9w",
+ "cm90b2J1Zi9zdHJ1Y3QucHJvdG8aH2dvb2dsZS9wcm90b2J1Zi90aW1lc3Rh",
+ "bXAucHJvdG8aHmdvb2dsZS9wcm90b2J1Zi93cmFwcGVycy5wcm90byKNAQoS",
+ "Q29uZm9ybWFuY2VSZXF1ZXN0EhoKEHByb3RvYnVmX3BheWxvYWQYASABKAxI",
+ "ABIWCgxqc29uX3BheWxvYWQYAiABKAlIABI4ChdyZXF1ZXN0ZWRfb3V0cHV0",
+ "X2Zvcm1hdBgDIAEoDjIXLmNvbmZvcm1hbmNlLldpcmVGb3JtYXRCCQoHcGF5",
+ "bG9hZCKxAQoTQ29uZm9ybWFuY2VSZXNwb25zZRIVCgtwYXJzZV9lcnJvchgB",
+ "IAEoCUgAEhkKD3NlcmlhbGl6ZV9lcnJvchgGIAEoCUgAEhcKDXJ1bnRpbWVf",
+ "ZXJyb3IYAiABKAlIABIaChBwcm90b2J1Zl9wYXlsb2FkGAMgASgMSAASFgoM",
+ "anNvbl9wYXlsb2FkGAQgASgJSAASEQoHc2tpcHBlZBgFIAEoCUgAQggKBnJl",
+ "c3VsdCLVMgoMVGVzdEFsbFR5cGVzEhYKDm9wdGlvbmFsX2ludDMyGAEgASgF",
+ "EhYKDm9wdGlvbmFsX2ludDY0GAIgASgDEhcKD29wdGlvbmFsX3VpbnQzMhgD",
+ "IAEoDRIXCg9vcHRpb25hbF91aW50NjQYBCABKAQSFwoPb3B0aW9uYWxfc2lu",
+ "dDMyGAUgASgREhcKD29wdGlvbmFsX3NpbnQ2NBgGIAEoEhIYChBvcHRpb25h",
+ "bF9maXhlZDMyGAcgASgHEhgKEG9wdGlvbmFsX2ZpeGVkNjQYCCABKAYSGQoR",
+ "b3B0aW9uYWxfc2ZpeGVkMzIYCSABKA8SGQoRb3B0aW9uYWxfc2ZpeGVkNjQY",
+ "CiABKBASFgoOb3B0aW9uYWxfZmxvYXQYCyABKAISFwoPb3B0aW9uYWxfZG91",
+ "YmxlGAwgASgBEhUKDW9wdGlvbmFsX2Jvb2wYDSABKAgSFwoPb3B0aW9uYWxf",
+ "c3RyaW5nGA4gASgJEhYKDm9wdGlvbmFsX2J5dGVzGA8gASgMEkgKF29wdGlv",
+ "bmFsX25lc3RlZF9tZXNzYWdlGBIgASgLMicuY29uZm9ybWFuY2UuVGVzdEFs",
+ "bFR5cGVzLk5lc3RlZE1lc3NhZ2USPQoYb3B0aW9uYWxfZm9yZWlnbl9tZXNz",
+ "YWdlGBMgASgLMhsuY29uZm9ybWFuY2UuRm9yZWlnbk1lc3NhZ2USQgoUb3B0",
+ "aW9uYWxfbmVzdGVkX2VudW0YFSABKA4yJC5jb25mb3JtYW5jZS5UZXN0QWxs",
+ "VHlwZXMuTmVzdGVkRW51bRI3ChVvcHRpb25hbF9mb3JlaWduX2VudW0YFiAB",
+ "KA4yGC5jb25mb3JtYW5jZS5Gb3JlaWduRW51bRIhChVvcHRpb25hbF9zdHJp",
+ "bmdfcGllY2UYGCABKAlCAggCEhkKDW9wdGlvbmFsX2NvcmQYGSABKAlCAggB",
+ "EjQKEXJlY3Vyc2l2ZV9tZXNzYWdlGBsgASgLMhkuY29uZm9ybWFuY2UuVGVz",
+ "dEFsbFR5cGVzEhYKDnJlcGVhdGVkX2ludDMyGB8gAygFEhYKDnJlcGVhdGVk",
+ "X2ludDY0GCAgAygDEhcKD3JlcGVhdGVkX3VpbnQzMhghIAMoDRIXCg9yZXBl",
+ "YXRlZF91aW50NjQYIiADKAQSFwoPcmVwZWF0ZWRfc2ludDMyGCMgAygREhcK",
+ "D3JlcGVhdGVkX3NpbnQ2NBgkIAMoEhIYChByZXBlYXRlZF9maXhlZDMyGCUg",
+ "AygHEhgKEHJlcGVhdGVkX2ZpeGVkNjQYJiADKAYSGQoRcmVwZWF0ZWRfc2Zp",
+ "eGVkMzIYJyADKA8SGQoRcmVwZWF0ZWRfc2ZpeGVkNjQYKCADKBASFgoOcmVw",
+ "ZWF0ZWRfZmxvYXQYKSADKAISFwoPcmVwZWF0ZWRfZG91YmxlGCogAygBEhUK",
+ "DXJlcGVhdGVkX2Jvb2wYKyADKAgSFwoPcmVwZWF0ZWRfc3RyaW5nGCwgAygJ",
+ "EhYKDnJlcGVhdGVkX2J5dGVzGC0gAygMEkgKF3JlcGVhdGVkX25lc3RlZF9t",
+ "ZXNzYWdlGDAgAygLMicuY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk5lc3Rl",
+ "ZE1lc3NhZ2USPQoYcmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlGDEgAygLMhsu",
+ "Y29uZm9ybWFuY2UuRm9yZWlnbk1lc3NhZ2USQgoUcmVwZWF0ZWRfbmVzdGVk",
+ "X2VudW0YMyADKA4yJC5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTmVzdGVk",
+ "RW51bRI3ChVyZXBlYXRlZF9mb3JlaWduX2VudW0YNCADKA4yGC5jb25mb3Jt",
+ "YW5jZS5Gb3JlaWduRW51bRIhChVyZXBlYXRlZF9zdHJpbmdfcGllY2UYNiAD",
+ "KAlCAggCEhkKDXJlcGVhdGVkX2NvcmQYNyADKAlCAggBEkUKD21hcF9pbnQz",
+ "Ml9pbnQzMhg4IAMoCzIsLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBJ",
+ "bnQzMkludDMyRW50cnkSRQoPbWFwX2ludDY0X2ludDY0GDkgAygLMiwuY29u",
+ "Zm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcEludDY0SW50NjRFbnRyeRJJChFt",
+ "YXBfdWludDMyX3VpbnQzMhg6IAMoCzIuLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
+ "eXBlcy5NYXBVaW50MzJVaW50MzJFbnRyeRJJChFtYXBfdWludDY0X3VpbnQ2",
+ "NBg7IAMoCzIuLmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBVaW50NjRV",
+ "aW50NjRFbnRyeRJJChFtYXBfc2ludDMyX3NpbnQzMhg8IAMoCzIuLmNvbmZv",
+ "cm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBTaW50MzJTaW50MzJFbnRyeRJJChFt",
+ "YXBfc2ludDY0X3NpbnQ2NBg9IAMoCzIuLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
+ "eXBlcy5NYXBTaW50NjRTaW50NjRFbnRyeRJNChNtYXBfZml4ZWQzMl9maXhl",
+ "ZDMyGD4gAygLMjAuY29uZm9ybWFuY2UuVGVzdEFsbFR5cGVzLk1hcEZpeGVk",
+ "MzJGaXhlZDMyRW50cnkSTQoTbWFwX2ZpeGVkNjRfZml4ZWQ2NBg/IAMoCzIw",
+ "LmNvbmZvcm1hbmNlLlRlc3RBbGxUeXBlcy5NYXBGaXhlZDY0Rml4ZWQ2NEVu",
+ "dHJ5ElEKFW1hcF9zZml4ZWQzMl9zZml4ZWQzMhhAIAMoCzIyLmNvbmZvcm1h",
+ "bmNlLlRlc3RBbGxUeXBlcy5NYXBTZml4ZWQzMlNmaXhlZDMyRW50cnkSUQoV",
+ "bWFwX3NmaXhlZDY0X3NmaXhlZDY0GEEgAygLMjIuY29uZm9ybWFuY2UuVGVz",
+ "dEFsbFR5cGVzLk1hcFNmaXhlZDY0U2ZpeGVkNjRFbnRyeRJFCg9tYXBfaW50",
+ "MzJfZmxvYXQYQiADKAsyLC5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFw",
+ "SW50MzJGbG9hdEVudHJ5EkcKEG1hcF9pbnQzMl9kb3VibGUYQyADKAsyLS5j",
+ "b25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwSW50MzJEb3VibGVFbnRyeRJB",
+ "Cg1tYXBfYm9vbF9ib29sGEQgAygLMiouY29uZm9ybWFuY2UuVGVzdEFsbFR5",
+ "cGVzLk1hcEJvb2xCb29sRW50cnkSSQoRbWFwX3N0cmluZ19zdHJpbmcYRSAD",
+ "KAsyLi5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMuTWFwU3RyaW5nU3RyaW5n",
+ "RW50cnkSRwoQbWFwX3N0cmluZ19ieXRlcxhGIAMoCzItLmNvbmZvcm1hbmNl",
+ "LlRlc3RBbGxUeXBlcy5NYXBTdHJpbmdCeXRlc0VudHJ5ElgKGW1hcF9zdHJp",
+ "bmdfbmVzdGVkX21lc3NhZ2UYRyADKAsyNS5jb25mb3JtYW5jZS5UZXN0QWxs",
+ "VHlwZXMuTWFwU3RyaW5nTmVzdGVkTWVzc2FnZUVudHJ5EloKGm1hcF9zdHJp",
+ "bmdfZm9yZWlnbl9tZXNzYWdlGEggAygLMjYuY29uZm9ybWFuY2UuVGVzdEFs",
+ "bFR5cGVzLk1hcFN0cmluZ0ZvcmVpZ25NZXNzYWdlRW50cnkSUgoWbWFwX3N0",
+ "cmluZ19uZXN0ZWRfZW51bRhJIAMoCzIyLmNvbmZvcm1hbmNlLlRlc3RBbGxU",
+ "eXBlcy5NYXBTdHJpbmdOZXN0ZWRFbnVtRW50cnkSVAoXbWFwX3N0cmluZ19m",
+ "b3JlaWduX2VudW0YSiADKAsyMy5jb25mb3JtYW5jZS5UZXN0QWxsVHlwZXMu",
+ "TWFwU3RyaW5nRm9yZWlnbkVudW1FbnRyeRIWCgxvbmVvZl91aW50MzIYbyAB",
+ "KA1IABJHChRvbmVvZl9uZXN0ZWRfbWVzc2FnZRhwIAEoCzInLmNvbmZvcm1h",
+ "bmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlSAASFgoMb25lb2Zfc3Ry",
+ "aW5nGHEgASgJSAASFQoLb25lb2ZfYnl0ZXMYciABKAxIABI6ChVvcHRpb25h",
+ "bF9ib29sX3dyYXBwZXIYyQEgASgLMhouZ29vZ2xlLnByb3RvYnVmLkJvb2xW",
+ "YWx1ZRI8ChZvcHRpb25hbF9pbnQzMl93cmFwcGVyGMoBIAEoCzIbLmdvb2ds",
+ "ZS5wcm90b2J1Zi5JbnQzMlZhbHVlEjwKFm9wdGlvbmFsX2ludDY0X3dyYXBw",
+ "ZXIYywEgASgLMhsuZ29vZ2xlLnByb3RvYnVmLkludDY0VmFsdWUSPgoXb3B0",
+ "aW9uYWxfdWludDMyX3dyYXBwZXIYzAEgASgLMhwuZ29vZ2xlLnByb3RvYnVm",
+ "LlVJbnQzMlZhbHVlEj4KF29wdGlvbmFsX3VpbnQ2NF93cmFwcGVyGM0BIAEo",
+ "CzIcLmdvb2dsZS5wcm90b2J1Zi5VSW50NjRWYWx1ZRI8ChZvcHRpb25hbF9m",
+ "bG9hdF93cmFwcGVyGM4BIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZh",
+ "bHVlEj4KF29wdGlvbmFsX2RvdWJsZV93cmFwcGVyGM8BIAEoCzIcLmdvb2ds",
+ "ZS5wcm90b2J1Zi5Eb3VibGVWYWx1ZRI+ChdvcHRpb25hbF9zdHJpbmdfd3Jh",
+ "cHBlchjQASABKAsyHC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSPAoW",
+ "b3B0aW9uYWxfYnl0ZXNfd3JhcHBlchjRASABKAsyGy5nb29nbGUucHJvdG9i",
+ "dWYuQnl0ZXNWYWx1ZRI6ChVyZXBlYXRlZF9ib29sX3dyYXBwZXIY0wEgAygL",
+ "MhouZ29vZ2xlLnByb3RvYnVmLkJvb2xWYWx1ZRI8ChZyZXBlYXRlZF9pbnQz",
+ "Ml93cmFwcGVyGNQBIAMoCzIbLmdvb2dsZS5wcm90b2J1Zi5JbnQzMlZhbHVl",
+ "EjwKFnJlcGVhdGVkX2ludDY0X3dyYXBwZXIY1QEgAygLMhsuZ29vZ2xlLnBy",
+ "b3RvYnVmLkludDY0VmFsdWUSPgoXcmVwZWF0ZWRfdWludDMyX3dyYXBwZXIY",
+ "1gEgAygLMhwuZ29vZ2xlLnByb3RvYnVmLlVJbnQzMlZhbHVlEj4KF3JlcGVh",
+ "dGVkX3VpbnQ2NF93cmFwcGVyGNcBIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5V",
+ "SW50NjRWYWx1ZRI8ChZyZXBlYXRlZF9mbG9hdF93cmFwcGVyGNgBIAMoCzIb",
+ "Lmdvb2dsZS5wcm90b2J1Zi5GbG9hdFZhbHVlEj4KF3JlcGVhdGVkX2RvdWJs",
+ "ZV93cmFwcGVyGNkBIAMoCzIcLmdvb2dsZS5wcm90b2J1Zi5Eb3VibGVWYWx1",
+ "ZRI+ChdyZXBlYXRlZF9zdHJpbmdfd3JhcHBlchjaASADKAsyHC5nb29nbGUu",
+ "cHJvdG9idWYuU3RyaW5nVmFsdWUSPAoWcmVwZWF0ZWRfYnl0ZXNfd3JhcHBl",
+ "chjbASADKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZRI1ChFvcHRp",
+ "b25hbF9kdXJhdGlvbhitAiABKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRp",
+ "b24SNwoSb3B0aW9uYWxfdGltZXN0YW1wGK4CIAEoCzIaLmdvb2dsZS5wcm90",
+ "b2J1Zi5UaW1lc3RhbXASOAoTb3B0aW9uYWxfZmllbGRfbWFzaxivAiABKAsy",
+ "Gi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrEjEKD29wdGlvbmFsX3N0cnVj",
+ "dBiwAiABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0EisKDG9wdGlvbmFs",
+ "X2FueRixAiABKAsyFC5nb29nbGUucHJvdG9idWYuQW55Ei8KDm9wdGlvbmFs",
+ "X3ZhbHVlGLICIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZRI1ChFyZXBl",
+ "YXRlZF9kdXJhdGlvbhi3AiADKAsyGS5nb29nbGUucHJvdG9idWYuRHVyYXRp",
+ "b24SNwoScmVwZWF0ZWRfdGltZXN0YW1wGLgCIAMoCzIaLmdvb2dsZS5wcm90",
+ "b2J1Zi5UaW1lc3RhbXASNwoScmVwZWF0ZWRfZmllbGRtYXNrGLkCIAMoCzIa",
+ "Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2sSMQoPcmVwZWF0ZWRfc3RydWN0",
+ "GMQCIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3QSKwoMcmVwZWF0ZWRf",
+ "YW55GLsCIAMoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkSLwoOcmVwZWF0ZWRf",
+ "dmFsdWUYvAIgAygLMhYuZ29vZ2xlLnByb3RvYnVmLlZhbHVlEhMKCmZpZWxk",
+ "bmFtZTEYkQMgASgFEhQKC2ZpZWxkX25hbWUyGJIDIAEoBRIVCgxfZmllbGRf",
+ "bmFtZTMYkwMgASgFEhYKDWZpZWxkX19uYW1lNF8YlAMgASgFEhQKC2ZpZWxk",
+ "MG5hbWU1GJUDIAEoBRIWCg1maWVsZF8wX25hbWU2GJYDIAEoBRITCgpmaWVs",
+ "ZE5hbWU3GJcDIAEoBRITCgpGaWVsZE5hbWU4GJgDIAEoBRIUCgtmaWVsZF9O",
+ "YW1lORiZAyABKAUSFQoMRmllbGRfTmFtZTEwGJoDIAEoBRIVCgxGSUVMRF9O",
+ "QU1FMTEYmwMgASgFEhUKDEZJRUxEX25hbWUxMhicAyABKAUaSgoNTmVzdGVk",
+ "TWVzc2FnZRIJCgFhGAEgASgFEi4KC2NvcmVjdXJzaXZlGAIgASgLMhkuY29u",
+ "Zm9ybWFuY2UuVGVzdEFsbFR5cGVzGjQKEk1hcEludDMySW50MzJFbnRyeRIL",
+ "CgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBGjQKEk1hcEludDY0SW50",
+ "NjRFbnRyeRILCgNrZXkYASABKAMSDQoFdmFsdWUYAiABKAM6AjgBGjYKFE1h",
+ "cFVpbnQzMlVpbnQzMkVudHJ5EgsKA2tleRgBIAEoDRINCgV2YWx1ZRgCIAEo",
+ "DToCOAEaNgoUTWFwVWludDY0VWludDY0RW50cnkSCwoDa2V5GAEgASgEEg0K",
+ "BXZhbHVlGAIgASgEOgI4ARo2ChRNYXBTaW50MzJTaW50MzJFbnRyeRILCgNr",
+ "ZXkYASABKBESDQoFdmFsdWUYAiABKBE6AjgBGjYKFE1hcFNpbnQ2NFNpbnQ2",
+ "NEVudHJ5EgsKA2tleRgBIAEoEhINCgV2YWx1ZRgCIAEoEjoCOAEaOAoWTWFw",
+ "Rml4ZWQzMkZpeGVkMzJFbnRyeRILCgNrZXkYASABKAcSDQoFdmFsdWUYAiAB",
+ "KAc6AjgBGjgKFk1hcEZpeGVkNjRGaXhlZDY0RW50cnkSCwoDa2V5GAEgASgG",
+ "Eg0KBXZhbHVlGAIgASgGOgI4ARo6ChhNYXBTZml4ZWQzMlNmaXhlZDMyRW50",
+ "cnkSCwoDa2V5GAEgASgPEg0KBXZhbHVlGAIgASgPOgI4ARo6ChhNYXBTZml4",
+ "ZWQ2NFNmaXhlZDY0RW50cnkSCwoDa2V5GAEgASgQEg0KBXZhbHVlGAIgASgQ",
+ "OgI4ARo0ChJNYXBJbnQzMkZsb2F0RW50cnkSCwoDa2V5GAEgASgFEg0KBXZh",
+ "bHVlGAIgASgCOgI4ARo1ChNNYXBJbnQzMkRvdWJsZUVudHJ5EgsKA2tleRgB",
+ "IAEoBRINCgV2YWx1ZRgCIAEoAToCOAEaMgoQTWFwQm9vbEJvb2xFbnRyeRIL",
+ "CgNrZXkYASABKAgSDQoFdmFsdWUYAiABKAg6AjgBGjYKFE1hcFN0cmluZ1N0",
+ "cmluZ0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaNQoT",
+ "TWFwU3RyaW5nQnl0ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiAB",
+ "KAw6AjgBGmYKG01hcFN0cmluZ05lc3RlZE1lc3NhZ2VFbnRyeRILCgNrZXkY",
+ "ASABKAkSNgoFdmFsdWUYAiABKAsyJy5jb25mb3JtYW5jZS5UZXN0QWxsVHlw",
+ "ZXMuTmVzdGVkTWVzc2FnZToCOAEaWwocTWFwU3RyaW5nRm9yZWlnbk1lc3Nh",
+ "Z2VFbnRyeRILCgNrZXkYASABKAkSKgoFdmFsdWUYAiABKAsyGy5jb25mb3Jt",
+ "YW5jZS5Gb3JlaWduTWVzc2FnZToCOAEaYAoYTWFwU3RyaW5nTmVzdGVkRW51",
+ "bUVudHJ5EgsKA2tleRgBIAEoCRIzCgV2YWx1ZRgCIAEoDjIkLmNvbmZvcm1h",
+ "bmNlLlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtOgI4ARpVChlNYXBTdHJpbmdG",
+ "b3JlaWduRW51bUVudHJ5EgsKA2tleRgBIAEoCRInCgV2YWx1ZRgCIAEoDjIY",
+ "LmNvbmZvcm1hbmNlLkZvcmVpZ25FbnVtOgI4ASI5CgpOZXN0ZWRFbnVtEgcK",
+ "A0ZPTxAAEgcKA0JBUhABEgcKA0JBWhACEhAKA05FRxD///////////8BQg0K",
+ "C29uZW9mX2ZpZWxkIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUqNQoK",
+ "V2lyZUZvcm1hdBIPCgtVTlNQRUNJRklFRBAAEgwKCFBST1RPQlVGEAESCAoE",
+ "SlNPThACKkAKC0ZvcmVpZ25FbnVtEg8KC0ZPUkVJR05fRk9PEAASDwoLRk9S",
+ "RUlHTl9CQVIQARIPCgtGT1JFSUdOX0JBWhACQiEKH2NvbS5nb29nbGUucHJv",
+ "dG9idWYuY29uZm9ybWFuY2ViBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Conformance.WireFormat), typeof(global::Conformance.ForeignEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceRequest), global::Conformance.ConformanceRequest.Parser, new[]{ "ProtobufPayload", "JsonPayload", "RequestedOutputFormat" }, new[]{ "Payload" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ConformanceResponse), global::Conformance.ConformanceResponse.Parser, new[]{ "ParseError", "SerializeError", "RuntimeError", "ProtobufPayload", "JsonPayload", "Skipped" }, new[]{ "Result" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.TestAllTypes), global::Conformance.TestAllTypes.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalStringPiece", "OptionalCord", "RecursiveMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapStringBytes", "MapStringNestedMessage", "MapStringForeignMessage", "MapStringNestedEnum", "MapStringForeignEnum", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", "OptionalBoolWrapper", "OptionalInt32Wrapper", "OptionalInt64Wrapper", "OptionalUint32Wrapper", "OptionalUint64Wrapper", "OptionalFloatWrapper", "OptionalDoubleWrapper", "OptionalStringWrapper", "OptionalBytesWrapper", "RepeatedBoolWrapper", "RepeatedInt32Wrapper", "RepeatedInt64Wrapper", "RepeatedUint32Wrapper", "RepeatedUint64Wrapper", "RepeatedFloatWrapper", "RepeatedDoubleWrapper", "RepeatedStringWrapper", "RepeatedBytesWrapper", "OptionalDuration", "OptionalTimestamp", "OptionalFieldMask", "OptionalStruct", "OptionalAny", "OptionalValue", "RepeatedDuration", "RepeatedTimestamp", "RepeatedFieldmask", "RepeatedStruct", "RepeatedAny", "RepeatedValue", "Fieldname1", "FieldName2", "FieldName3", "FieldName4", "Field0Name5", "Field0Name6", "FieldName7", "FieldName8", "FieldName9", "FieldName10", "FIELDNAME11", "FIELDName12" }, new[]{ "OneofField" }, new[]{ typeof(global::Conformance.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.TestAllTypes.Types.NestedMessage), global::Conformance.TestAllTypes.Types.NestedMessage.Parser, new[]{ "A", "Corecursive" }, null, null, null),
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Conformance.ForeignMessage), new[]{ "C" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Conformance.ForeignMessage), global::Conformance.ForeignMessage.Parser, new[]{ "C" }, null, null, null)
}));
}
#endregion
@@ -149,15 +199,15 @@ namespace Conformance {
}
#region Enums
public enum WireFormat {
- UNSPECIFIED = 0,
- PROTOBUF = 1,
- JSON = 2,
+ [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("PROTOBUF")] Protobuf = 1,
+ [pbr::OriginalName("JSON")] Json = 2,
}
public enum ForeignEnum {
- FOREIGN_FOO = 0,
- FOREIGN_BAR = 1,
- FOREIGN_BAZ = 2,
+ [pbr::OriginalName("FOREIGN_FOO")] ForeignFoo = 0,
+ [pbr::OriginalName("FOREIGN_BAR")] ForeignBar = 1,
+ [pbr::OriginalName("FOREIGN_BAZ")] ForeignBaz = 2,
}
#endregion
@@ -165,6 +215,7 @@ namespace Conformance {
#region Messages
/// <summary>
/// Represents a single test case's input. The testee should:
+ ///
/// 1. parse this proto (which should always succeed)
/// 2. parse the protobuf or JSON payload in "payload" (which may fail)
/// 3. if the parse succeeded, serialize the message in the requested format.
@@ -175,7 +226,7 @@ namespace Conformance {
public static pb::MessageParser<ConformanceRequest> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Conformance.Conformance.Descriptor.MessageTypes[0]; }
+ get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -210,7 +261,7 @@ namespace Conformance {
public pb::ByteString ProtobufPayload {
get { return payloadCase_ == PayloadOneofCase.ProtobufPayload ? (pb::ByteString) payload_ : pb::ByteString.Empty; }
set {
- payload_ = pb::Preconditions.CheckNotNull(value, "value");
+ payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
payloadCase_ = PayloadOneofCase.ProtobufPayload;
}
}
@@ -220,14 +271,14 @@ namespace Conformance {
public string JsonPayload {
get { return payloadCase_ == PayloadOneofCase.JsonPayload ? (string) payload_ : ""; }
set {
- payload_ = pb::Preconditions.CheckNotNull(value, "value");
+ payload_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
payloadCase_ = PayloadOneofCase.JsonPayload;
}
}
/// <summary>Field number for the "requested_output_format" field.</summary>
public const int RequestedOutputFormatFieldNumber = 3;
- private global::Conformance.WireFormat requestedOutputFormat_ = global::Conformance.WireFormat.UNSPECIFIED;
+ private global::Conformance.WireFormat requestedOutputFormat_ = 0;
/// <summary>
/// Which format should the testee serialize its message to?
/// </summary>
@@ -269,6 +320,7 @@ namespace Conformance {
if (ProtobufPayload != other.ProtobufPayload) return false;
if (JsonPayload != other.JsonPayload) return false;
if (RequestedOutputFormat != other.RequestedOutputFormat) return false;
+ if (PayloadCase != other.PayloadCase) return false;
return true;
}
@@ -276,12 +328,13 @@ namespace Conformance {
int hash = 1;
if (payloadCase_ == PayloadOneofCase.ProtobufPayload) hash ^= ProtobufPayload.GetHashCode();
if (payloadCase_ == PayloadOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode();
- if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) hash ^= RequestedOutputFormat.GetHashCode();
+ if (RequestedOutputFormat != 0) hash ^= RequestedOutputFormat.GetHashCode();
+ hash ^= (int) payloadCase_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -293,7 +346,7 @@ namespace Conformance {
output.WriteRawTag(18);
output.WriteString(JsonPayload);
}
- if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
+ if (RequestedOutputFormat != 0) {
output.WriteRawTag(24);
output.WriteEnum((int) RequestedOutputFormat);
}
@@ -307,7 +360,7 @@ namespace Conformance {
if (payloadCase_ == PayloadOneofCase.JsonPayload) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonPayload);
}
- if (RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
+ if (RequestedOutputFormat != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) RequestedOutputFormat);
}
return size;
@@ -317,7 +370,7 @@ namespace Conformance {
if (other == null) {
return;
}
- if (other.RequestedOutputFormat != global::Conformance.WireFormat.UNSPECIFIED) {
+ if (other.RequestedOutputFormat != 0) {
RequestedOutputFormat = other.RequestedOutputFormat;
}
switch (other.PayloadCase) {
@@ -365,7 +418,7 @@ namespace Conformance {
public static pb::MessageParser<ConformanceResponse> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Conformance.Conformance.Descriptor.MessageTypes[1]; }
+ get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -383,6 +436,9 @@ namespace Conformance {
case ResultOneofCase.ParseError:
ParseError = other.ParseError;
break;
+ case ResultOneofCase.SerializeError:
+ SerializeError = other.SerializeError;
+ break;
case ResultOneofCase.RuntimeError:
RuntimeError = other.RuntimeError;
break;
@@ -408,17 +464,33 @@ namespace Conformance {
/// <summary>
/// This string should be set to indicate parsing failed. The string can
/// provide more information about the parse error if it is available.
+ ///
/// Setting this string does not necessarily mean the testee failed the
/// test. Some of the test cases are intentionally invalid input.
/// </summary>
public string ParseError {
get { return resultCase_ == ResultOneofCase.ParseError ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.ParseError;
}
}
+ /// <summary>Field number for the "serialize_error" field.</summary>
+ public const int SerializeErrorFieldNumber = 6;
+ /// <summary>
+ /// If the input was successfully parsed but errors occurred when
+ /// serializing it to the requested output format, set the error message in
+ /// this field.
+ /// </summary>
+ public string SerializeError {
+ get { return resultCase_ == ResultOneofCase.SerializeError ? (string) result_ : ""; }
+ set {
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ resultCase_ = ResultOneofCase.SerializeError;
+ }
+ }
+
/// <summary>Field number for the "runtime_error" field.</summary>
public const int RuntimeErrorFieldNumber = 2;
/// <summary>
@@ -429,7 +501,7 @@ namespace Conformance {
public string RuntimeError {
get { return resultCase_ == ResultOneofCase.RuntimeError ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.RuntimeError;
}
}
@@ -443,7 +515,7 @@ namespace Conformance {
public pb::ByteString ProtobufPayload {
get { return resultCase_ == ResultOneofCase.ProtobufPayload ? (pb::ByteString) result_ : pb::ByteString.Empty; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.ProtobufPayload;
}
}
@@ -457,7 +529,7 @@ namespace Conformance {
public string JsonPayload {
get { return resultCase_ == ResultOneofCase.JsonPayload ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.JsonPayload;
}
}
@@ -471,7 +543,7 @@ namespace Conformance {
public string Skipped {
get { return resultCase_ == ResultOneofCase.Skipped ? (string) result_ : ""; }
set {
- result_ = pb::Preconditions.CheckNotNull(value, "value");
+ result_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
resultCase_ = ResultOneofCase.Skipped;
}
}
@@ -481,6 +553,7 @@ namespace Conformance {
public enum ResultOneofCase {
None = 0,
ParseError = 1,
+ SerializeError = 6,
RuntimeError = 2,
ProtobufPayload = 3,
JsonPayload = 4,
@@ -508,25 +581,29 @@ namespace Conformance {
return true;
}
if (ParseError != other.ParseError) return false;
+ if (SerializeError != other.SerializeError) return false;
if (RuntimeError != other.RuntimeError) return false;
if (ProtobufPayload != other.ProtobufPayload) return false;
if (JsonPayload != other.JsonPayload) return false;
if (Skipped != other.Skipped) return false;
+ if (ResultCase != other.ResultCase) return false;
return true;
}
public override int GetHashCode() {
int hash = 1;
if (resultCase_ == ResultOneofCase.ParseError) hash ^= ParseError.GetHashCode();
+ if (resultCase_ == ResultOneofCase.SerializeError) hash ^= SerializeError.GetHashCode();
if (resultCase_ == ResultOneofCase.RuntimeError) hash ^= RuntimeError.GetHashCode();
if (resultCase_ == ResultOneofCase.ProtobufPayload) hash ^= ProtobufPayload.GetHashCode();
if (resultCase_ == ResultOneofCase.JsonPayload) hash ^= JsonPayload.GetHashCode();
if (resultCase_ == ResultOneofCase.Skipped) hash ^= Skipped.GetHashCode();
+ hash ^= (int) resultCase_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -550,6 +627,10 @@ namespace Conformance {
output.WriteRawTag(42);
output.WriteString(Skipped);
}
+ if (resultCase_ == ResultOneofCase.SerializeError) {
+ output.WriteRawTag(50);
+ output.WriteString(SerializeError);
+ }
}
public int CalculateSize() {
@@ -557,6 +638,9 @@ namespace Conformance {
if (resultCase_ == ResultOneofCase.ParseError) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(ParseError);
}
+ if (resultCase_ == ResultOneofCase.SerializeError) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(SerializeError);
+ }
if (resultCase_ == ResultOneofCase.RuntimeError) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(RuntimeError);
}
@@ -580,6 +664,9 @@ namespace Conformance {
case ResultOneofCase.ParseError:
ParseError = other.ParseError;
break;
+ case ResultOneofCase.SerializeError:
+ SerializeError = other.SerializeError;
+ break;
case ResultOneofCase.RuntimeError:
RuntimeError = other.RuntimeError;
break;
@@ -623,6 +710,10 @@ namespace Conformance {
Skipped = input.ReadString();
break;
}
+ case 50: {
+ SerializeError = input.ReadString();
+ break;
+ }
}
}
}
@@ -639,7 +730,7 @@ namespace Conformance {
public static pb::MessageParser<TestAllTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Conformance.Conformance.Descriptor.MessageTypes[2]; }
+ get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -715,6 +806,48 @@ namespace Conformance {
mapStringForeignMessage_ = other.mapStringForeignMessage_.Clone();
mapStringNestedEnum_ = other.mapStringNestedEnum_.Clone();
mapStringForeignEnum_ = other.mapStringForeignEnum_.Clone();
+ OptionalBoolWrapper = other.OptionalBoolWrapper;
+ OptionalInt32Wrapper = other.OptionalInt32Wrapper;
+ OptionalInt64Wrapper = other.OptionalInt64Wrapper;
+ OptionalUint32Wrapper = other.OptionalUint32Wrapper;
+ OptionalUint64Wrapper = other.OptionalUint64Wrapper;
+ OptionalFloatWrapper = other.OptionalFloatWrapper;
+ OptionalDoubleWrapper = other.OptionalDoubleWrapper;
+ OptionalStringWrapper = other.OptionalStringWrapper;
+ OptionalBytesWrapper = other.OptionalBytesWrapper;
+ repeatedBoolWrapper_ = other.repeatedBoolWrapper_.Clone();
+ repeatedInt32Wrapper_ = other.repeatedInt32Wrapper_.Clone();
+ repeatedInt64Wrapper_ = other.repeatedInt64Wrapper_.Clone();
+ repeatedUint32Wrapper_ = other.repeatedUint32Wrapper_.Clone();
+ repeatedUint64Wrapper_ = other.repeatedUint64Wrapper_.Clone();
+ repeatedFloatWrapper_ = other.repeatedFloatWrapper_.Clone();
+ repeatedDoubleWrapper_ = other.repeatedDoubleWrapper_.Clone();
+ repeatedStringWrapper_ = other.repeatedStringWrapper_.Clone();
+ repeatedBytesWrapper_ = other.repeatedBytesWrapper_.Clone();
+ OptionalDuration = other.optionalDuration_ != null ? other.OptionalDuration.Clone() : null;
+ OptionalTimestamp = other.optionalTimestamp_ != null ? other.OptionalTimestamp.Clone() : null;
+ OptionalFieldMask = other.optionalFieldMask_ != null ? other.OptionalFieldMask.Clone() : null;
+ OptionalStruct = other.optionalStruct_ != null ? other.OptionalStruct.Clone() : null;
+ OptionalAny = other.optionalAny_ != null ? other.OptionalAny.Clone() : null;
+ OptionalValue = other.optionalValue_ != null ? other.OptionalValue.Clone() : null;
+ repeatedDuration_ = other.repeatedDuration_.Clone();
+ repeatedTimestamp_ = other.repeatedTimestamp_.Clone();
+ repeatedFieldmask_ = other.repeatedFieldmask_.Clone();
+ repeatedStruct_ = other.repeatedStruct_.Clone();
+ repeatedAny_ = other.repeatedAny_.Clone();
+ repeatedValue_ = other.repeatedValue_.Clone();
+ fieldname1_ = other.fieldname1_;
+ fieldName2_ = other.fieldName2_;
+ FieldName3_ = other.FieldName3_;
+ fieldName4_ = other.fieldName4_;
+ field0Name5_ = other.field0Name5_;
+ field0Name6_ = other.field0Name6_;
+ fieldName7_ = other.fieldName7_;
+ fieldName8_ = other.fieldName8_;
+ fieldName9_ = other.fieldName9_;
+ fieldName10_ = other.fieldName10_;
+ fIELDNAME11_ = other.fIELDNAME11_;
+ fIELDName12_ = other.fIELDName12_;
switch (other.OneofFieldCase) {
case OneofFieldOneofCase.OneofUint32:
OneofUint32 = other.OneofUint32;
@@ -875,7 +1008,7 @@ namespace Conformance {
public string OptionalString {
get { return optionalString_; }
set {
- optionalString_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -885,7 +1018,7 @@ namespace Conformance {
public pb::ByteString OptionalBytes {
get { return optionalBytes_; }
set {
- optionalBytes_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -911,7 +1044,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_nested_enum" field.</summary>
public const int OptionalNestedEnumFieldNumber = 21;
- private global::Conformance.TestAllTypes.Types.NestedEnum optionalNestedEnum_ = global::Conformance.TestAllTypes.Types.NestedEnum.FOO;
+ private global::Conformance.TestAllTypes.Types.NestedEnum optionalNestedEnum_ = 0;
public global::Conformance.TestAllTypes.Types.NestedEnum OptionalNestedEnum {
get { return optionalNestedEnum_; }
set {
@@ -921,7 +1054,7 @@ namespace Conformance {
/// <summary>Field number for the "optional_foreign_enum" field.</summary>
public const int OptionalForeignEnumFieldNumber = 22;
- private global::Conformance.ForeignEnum optionalForeignEnum_ = global::Conformance.ForeignEnum.FOREIGN_FOO;
+ private global::Conformance.ForeignEnum optionalForeignEnum_ = 0;
public global::Conformance.ForeignEnum OptionalForeignEnum {
get { return optionalForeignEnum_; }
set {
@@ -935,7 +1068,7 @@ namespace Conformance {
public string OptionalStringPiece {
get { return optionalStringPiece_; }
set {
- optionalStringPiece_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalStringPiece_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -945,7 +1078,7 @@ namespace Conformance {
public string OptionalCord {
get { return optionalCord_; }
set {
- optionalCord_ = pb::Preconditions.CheckNotNull(value, "value");
+ optionalCord_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1350,7 +1483,7 @@ namespace Conformance {
public string OneofString {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofString ? (string) oneofField_ : ""; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofString;
}
}
@@ -1360,11 +1493,431 @@ namespace Conformance {
public pb::ByteString OneofBytes {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofBytes ? (pb::ByteString) oneofField_ : pb::ByteString.Empty; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofBytes;
}
}
+ /// <summary>Field number for the "optional_bool_wrapper" field.</summary>
+ public const int OptionalBoolWrapperFieldNumber = 201;
+ private static readonly pb::FieldCodec<bool?> _single_optionalBoolWrapper_codec = pb::FieldCodec.ForStructWrapper<bool>(1610);
+ private bool? optionalBoolWrapper_;
+ /// <summary>
+ /// Well-known types
+ /// </summary>
+ public bool? OptionalBoolWrapper {
+ get { return optionalBoolWrapper_; }
+ set {
+ optionalBoolWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_int32_wrapper" field.</summary>
+ public const int OptionalInt32WrapperFieldNumber = 202;
+ private static readonly pb::FieldCodec<int?> _single_optionalInt32Wrapper_codec = pb::FieldCodec.ForStructWrapper<int>(1618);
+ private int? optionalInt32Wrapper_;
+ public int? OptionalInt32Wrapper {
+ get { return optionalInt32Wrapper_; }
+ set {
+ optionalInt32Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_int64_wrapper" field.</summary>
+ public const int OptionalInt64WrapperFieldNumber = 203;
+ private static readonly pb::FieldCodec<long?> _single_optionalInt64Wrapper_codec = pb::FieldCodec.ForStructWrapper<long>(1626);
+ private long? optionalInt64Wrapper_;
+ public long? OptionalInt64Wrapper {
+ get { return optionalInt64Wrapper_; }
+ set {
+ optionalInt64Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_uint32_wrapper" field.</summary>
+ public const int OptionalUint32WrapperFieldNumber = 204;
+ private static readonly pb::FieldCodec<uint?> _single_optionalUint32Wrapper_codec = pb::FieldCodec.ForStructWrapper<uint>(1634);
+ private uint? optionalUint32Wrapper_;
+ public uint? OptionalUint32Wrapper {
+ get { return optionalUint32Wrapper_; }
+ set {
+ optionalUint32Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_uint64_wrapper" field.</summary>
+ public const int OptionalUint64WrapperFieldNumber = 205;
+ private static readonly pb::FieldCodec<ulong?> _single_optionalUint64Wrapper_codec = pb::FieldCodec.ForStructWrapper<ulong>(1642);
+ private ulong? optionalUint64Wrapper_;
+ public ulong? OptionalUint64Wrapper {
+ get { return optionalUint64Wrapper_; }
+ set {
+ optionalUint64Wrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_float_wrapper" field.</summary>
+ public const int OptionalFloatWrapperFieldNumber = 206;
+ private static readonly pb::FieldCodec<float?> _single_optionalFloatWrapper_codec = pb::FieldCodec.ForStructWrapper<float>(1650);
+ private float? optionalFloatWrapper_;
+ public float? OptionalFloatWrapper {
+ get { return optionalFloatWrapper_; }
+ set {
+ optionalFloatWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_double_wrapper" field.</summary>
+ public const int OptionalDoubleWrapperFieldNumber = 207;
+ private static readonly pb::FieldCodec<double?> _single_optionalDoubleWrapper_codec = pb::FieldCodec.ForStructWrapper<double>(1658);
+ private double? optionalDoubleWrapper_;
+ public double? OptionalDoubleWrapper {
+ get { return optionalDoubleWrapper_; }
+ set {
+ optionalDoubleWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_string_wrapper" field.</summary>
+ public const int OptionalStringWrapperFieldNumber = 208;
+ private static readonly pb::FieldCodec<string> _single_optionalStringWrapper_codec = pb::FieldCodec.ForClassWrapper<string>(1666);
+ private string optionalStringWrapper_;
+ public string OptionalStringWrapper {
+ get { return optionalStringWrapper_; }
+ set {
+ optionalStringWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_bytes_wrapper" field.</summary>
+ public const int OptionalBytesWrapperFieldNumber = 209;
+ private static readonly pb::FieldCodec<pb::ByteString> _single_optionalBytesWrapper_codec = pb::FieldCodec.ForClassWrapper<pb::ByteString>(1674);
+ private pb::ByteString optionalBytesWrapper_;
+ public pb::ByteString OptionalBytesWrapper {
+ get { return optionalBytesWrapper_; }
+ set {
+ optionalBytesWrapper_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "repeated_bool_wrapper" field.</summary>
+ public const int RepeatedBoolWrapperFieldNumber = 211;
+ private static readonly pb::FieldCodec<bool?> _repeated_repeatedBoolWrapper_codec
+ = pb::FieldCodec.ForStructWrapper<bool>(1690);
+ private readonly pbc::RepeatedField<bool?> repeatedBoolWrapper_ = new pbc::RepeatedField<bool?>();
+ public pbc::RepeatedField<bool?> RepeatedBoolWrapper {
+ get { return repeatedBoolWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_int32_wrapper" field.</summary>
+ public const int RepeatedInt32WrapperFieldNumber = 212;
+ private static readonly pb::FieldCodec<int?> _repeated_repeatedInt32Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<int>(1698);
+ private readonly pbc::RepeatedField<int?> repeatedInt32Wrapper_ = new pbc::RepeatedField<int?>();
+ public pbc::RepeatedField<int?> RepeatedInt32Wrapper {
+ get { return repeatedInt32Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_int64_wrapper" field.</summary>
+ public const int RepeatedInt64WrapperFieldNumber = 213;
+ private static readonly pb::FieldCodec<long?> _repeated_repeatedInt64Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<long>(1706);
+ private readonly pbc::RepeatedField<long?> repeatedInt64Wrapper_ = new pbc::RepeatedField<long?>();
+ public pbc::RepeatedField<long?> RepeatedInt64Wrapper {
+ get { return repeatedInt64Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_uint32_wrapper" field.</summary>
+ public const int RepeatedUint32WrapperFieldNumber = 214;
+ private static readonly pb::FieldCodec<uint?> _repeated_repeatedUint32Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<uint>(1714);
+ private readonly pbc::RepeatedField<uint?> repeatedUint32Wrapper_ = new pbc::RepeatedField<uint?>();
+ public pbc::RepeatedField<uint?> RepeatedUint32Wrapper {
+ get { return repeatedUint32Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_uint64_wrapper" field.</summary>
+ public const int RepeatedUint64WrapperFieldNumber = 215;
+ private static readonly pb::FieldCodec<ulong?> _repeated_repeatedUint64Wrapper_codec
+ = pb::FieldCodec.ForStructWrapper<ulong>(1722);
+ private readonly pbc::RepeatedField<ulong?> repeatedUint64Wrapper_ = new pbc::RepeatedField<ulong?>();
+ public pbc::RepeatedField<ulong?> RepeatedUint64Wrapper {
+ get { return repeatedUint64Wrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_float_wrapper" field.</summary>
+ public const int RepeatedFloatWrapperFieldNumber = 216;
+ private static readonly pb::FieldCodec<float?> _repeated_repeatedFloatWrapper_codec
+ = pb::FieldCodec.ForStructWrapper<float>(1730);
+ private readonly pbc::RepeatedField<float?> repeatedFloatWrapper_ = new pbc::RepeatedField<float?>();
+ public pbc::RepeatedField<float?> RepeatedFloatWrapper {
+ get { return repeatedFloatWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_double_wrapper" field.</summary>
+ public const int RepeatedDoubleWrapperFieldNumber = 217;
+ private static readonly pb::FieldCodec<double?> _repeated_repeatedDoubleWrapper_codec
+ = pb::FieldCodec.ForStructWrapper<double>(1738);
+ private readonly pbc::RepeatedField<double?> repeatedDoubleWrapper_ = new pbc::RepeatedField<double?>();
+ public pbc::RepeatedField<double?> RepeatedDoubleWrapper {
+ get { return repeatedDoubleWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_string_wrapper" field.</summary>
+ public const int RepeatedStringWrapperFieldNumber = 218;
+ private static readonly pb::FieldCodec<string> _repeated_repeatedStringWrapper_codec
+ = pb::FieldCodec.ForClassWrapper<string>(1746);
+ private readonly pbc::RepeatedField<string> repeatedStringWrapper_ = new pbc::RepeatedField<string>();
+ public pbc::RepeatedField<string> RepeatedStringWrapper {
+ get { return repeatedStringWrapper_; }
+ }
+
+ /// <summary>Field number for the "repeated_bytes_wrapper" field.</summary>
+ public const int RepeatedBytesWrapperFieldNumber = 219;
+ private static readonly pb::FieldCodec<pb::ByteString> _repeated_repeatedBytesWrapper_codec
+ = pb::FieldCodec.ForClassWrapper<pb::ByteString>(1754);
+ private readonly pbc::RepeatedField<pb::ByteString> repeatedBytesWrapper_ = new pbc::RepeatedField<pb::ByteString>();
+ public pbc::RepeatedField<pb::ByteString> RepeatedBytesWrapper {
+ get { return repeatedBytesWrapper_; }
+ }
+
+ /// <summary>Field number for the "optional_duration" field.</summary>
+ public const int OptionalDurationFieldNumber = 301;
+ private global::Google.Protobuf.WellKnownTypes.Duration optionalDuration_;
+ public global::Google.Protobuf.WellKnownTypes.Duration OptionalDuration {
+ get { return optionalDuration_; }
+ set {
+ optionalDuration_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_timestamp" field.</summary>
+ public const int OptionalTimestampFieldNumber = 302;
+ private global::Google.Protobuf.WellKnownTypes.Timestamp optionalTimestamp_;
+ public global::Google.Protobuf.WellKnownTypes.Timestamp OptionalTimestamp {
+ get { return optionalTimestamp_; }
+ set {
+ optionalTimestamp_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_field_mask" field.</summary>
+ public const int OptionalFieldMaskFieldNumber = 303;
+ private global::Google.Protobuf.WellKnownTypes.FieldMask optionalFieldMask_;
+ public global::Google.Protobuf.WellKnownTypes.FieldMask OptionalFieldMask {
+ get { return optionalFieldMask_; }
+ set {
+ optionalFieldMask_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_struct" field.</summary>
+ public const int OptionalStructFieldNumber = 304;
+ private global::Google.Protobuf.WellKnownTypes.Struct optionalStruct_;
+ public global::Google.Protobuf.WellKnownTypes.Struct OptionalStruct {
+ get { return optionalStruct_; }
+ set {
+ optionalStruct_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_any" field.</summary>
+ public const int OptionalAnyFieldNumber = 305;
+ private global::Google.Protobuf.WellKnownTypes.Any optionalAny_;
+ public global::Google.Protobuf.WellKnownTypes.Any OptionalAny {
+ get { return optionalAny_; }
+ set {
+ optionalAny_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "optional_value" field.</summary>
+ public const int OptionalValueFieldNumber = 306;
+ private global::Google.Protobuf.WellKnownTypes.Value optionalValue_;
+ public global::Google.Protobuf.WellKnownTypes.Value OptionalValue {
+ get { return optionalValue_; }
+ set {
+ optionalValue_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "repeated_duration" field.</summary>
+ public const int RepeatedDurationFieldNumber = 311;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Duration> _repeated_repeatedDuration_codec
+ = pb::FieldCodec.ForMessage(2490, global::Google.Protobuf.WellKnownTypes.Duration.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration> repeatedDuration_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration>();
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Duration> RepeatedDuration {
+ get { return repeatedDuration_; }
+ }
+
+ /// <summary>Field number for the "repeated_timestamp" field.</summary>
+ public const int RepeatedTimestampFieldNumber = 312;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Timestamp> _repeated_repeatedTimestamp_codec
+ = pb::FieldCodec.ForMessage(2498, global::Google.Protobuf.WellKnownTypes.Timestamp.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp> repeatedTimestamp_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp>();
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Timestamp> RepeatedTimestamp {
+ get { return repeatedTimestamp_; }
+ }
+
+ /// <summary>Field number for the "repeated_fieldmask" field.</summary>
+ public const int RepeatedFieldmaskFieldNumber = 313;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.FieldMask> _repeated_repeatedFieldmask_codec
+ = pb::FieldCodec.ForMessage(2506, global::Google.Protobuf.WellKnownTypes.FieldMask.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask> repeatedFieldmask_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask>();
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.FieldMask> RepeatedFieldmask {
+ get { return repeatedFieldmask_; }
+ }
+
+ /// <summary>Field number for the "repeated_struct" field.</summary>
+ public const int RepeatedStructFieldNumber = 324;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Struct> _repeated_repeatedStruct_codec
+ = pb::FieldCodec.ForMessage(2594, global::Google.Protobuf.WellKnownTypes.Struct.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct> repeatedStruct_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct>();
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Struct> RepeatedStruct {
+ get { return repeatedStruct_; }
+ }
+
+ /// <summary>Field number for the "repeated_any" field.</summary>
+ public const int RepeatedAnyFieldNumber = 315;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Any> _repeated_repeatedAny_codec
+ = pb::FieldCodec.ForMessage(2522, global::Google.Protobuf.WellKnownTypes.Any.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any> repeatedAny_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any>();
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Any> RepeatedAny {
+ get { return repeatedAny_; }
+ }
+
+ /// <summary>Field number for the "repeated_value" field.</summary>
+ public const int RepeatedValueFieldNumber = 316;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Value> _repeated_repeatedValue_codec
+ = pb::FieldCodec.ForMessage(2530, global::Google.Protobuf.WellKnownTypes.Value.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value> repeatedValue_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value>();
+ public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value> RepeatedValue {
+ get { return repeatedValue_; }
+ }
+
+ /// <summary>Field number for the "fieldname1" field.</summary>
+ public const int Fieldname1FieldNumber = 401;
+ private int fieldname1_;
+ /// <summary>
+ /// Test field-name-to-JSON-name convention.
+ /// </summary>
+ public int Fieldname1 {
+ get { return fieldname1_; }
+ set {
+ fieldname1_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field_name2" field.</summary>
+ public const int FieldName2FieldNumber = 402;
+ private int fieldName2_;
+ public int FieldName2 {
+ get { return fieldName2_; }
+ set {
+ fieldName2_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "_field_name3" field.</summary>
+ public const int FieldName3FieldNumber = 403;
+ private int FieldName3_;
+ public int FieldName3 {
+ get { return FieldName3_; }
+ set {
+ FieldName3_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field__name4_" field.</summary>
+ public const int FieldName4FieldNumber = 404;
+ private int fieldName4_;
+ public int FieldName4 {
+ get { return fieldName4_; }
+ set {
+ fieldName4_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field0name5" field.</summary>
+ public const int Field0Name5FieldNumber = 405;
+ private int field0Name5_;
+ public int Field0Name5 {
+ get { return field0Name5_; }
+ set {
+ field0Name5_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field_0_name6" field.</summary>
+ public const int Field0Name6FieldNumber = 406;
+ private int field0Name6_;
+ public int Field0Name6 {
+ get { return field0Name6_; }
+ set {
+ field0Name6_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "fieldName7" field.</summary>
+ public const int FieldName7FieldNumber = 407;
+ private int fieldName7_;
+ public int FieldName7 {
+ get { return fieldName7_; }
+ set {
+ fieldName7_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "FieldName8" field.</summary>
+ public const int FieldName8FieldNumber = 408;
+ private int fieldName8_;
+ public int FieldName8 {
+ get { return fieldName8_; }
+ set {
+ fieldName8_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "field_Name9" field.</summary>
+ public const int FieldName9FieldNumber = 409;
+ private int fieldName9_;
+ public int FieldName9 {
+ get { return fieldName9_; }
+ set {
+ fieldName9_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "Field_Name10" field.</summary>
+ public const int FieldName10FieldNumber = 410;
+ private int fieldName10_;
+ public int FieldName10 {
+ get { return fieldName10_; }
+ set {
+ fieldName10_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "FIELD_NAME11" field.</summary>
+ public const int FIELDNAME11FieldNumber = 411;
+ private int fIELDNAME11_;
+ public int FIELDNAME11 {
+ get { return fIELDNAME11_; }
+ set {
+ fIELDNAME11_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "FIELD_name12" field.</summary>
+ public const int FIELDName12FieldNumber = 412;
+ private int fIELDName12_;
+ public int FIELDName12 {
+ get { return fIELDName12_; }
+ set {
+ fIELDName12_ = value;
+ }
+ }
+
private object oneofField_;
/// <summary>Enum of possible cases for the "oneof_field" oneof.</summary>
public enum OneofFieldOneofCase {
@@ -1461,6 +2014,49 @@ namespace Conformance {
if (!object.Equals(OneofNestedMessage, other.OneofNestedMessage)) return false;
if (OneofString != other.OneofString) return false;
if (OneofBytes != other.OneofBytes) return false;
+ if (OptionalBoolWrapper != other.OptionalBoolWrapper) return false;
+ if (OptionalInt32Wrapper != other.OptionalInt32Wrapper) return false;
+ if (OptionalInt64Wrapper != other.OptionalInt64Wrapper) return false;
+ if (OptionalUint32Wrapper != other.OptionalUint32Wrapper) return false;
+ if (OptionalUint64Wrapper != other.OptionalUint64Wrapper) return false;
+ if (OptionalFloatWrapper != other.OptionalFloatWrapper) return false;
+ if (OptionalDoubleWrapper != other.OptionalDoubleWrapper) return false;
+ if (OptionalStringWrapper != other.OptionalStringWrapper) return false;
+ if (OptionalBytesWrapper != other.OptionalBytesWrapper) return false;
+ if(!repeatedBoolWrapper_.Equals(other.repeatedBoolWrapper_)) return false;
+ if(!repeatedInt32Wrapper_.Equals(other.repeatedInt32Wrapper_)) return false;
+ if(!repeatedInt64Wrapper_.Equals(other.repeatedInt64Wrapper_)) return false;
+ if(!repeatedUint32Wrapper_.Equals(other.repeatedUint32Wrapper_)) return false;
+ if(!repeatedUint64Wrapper_.Equals(other.repeatedUint64Wrapper_)) return false;
+ if(!repeatedFloatWrapper_.Equals(other.repeatedFloatWrapper_)) return false;
+ if(!repeatedDoubleWrapper_.Equals(other.repeatedDoubleWrapper_)) return false;
+ if(!repeatedStringWrapper_.Equals(other.repeatedStringWrapper_)) return false;
+ if(!repeatedBytesWrapper_.Equals(other.repeatedBytesWrapper_)) return false;
+ if (!object.Equals(OptionalDuration, other.OptionalDuration)) return false;
+ if (!object.Equals(OptionalTimestamp, other.OptionalTimestamp)) return false;
+ if (!object.Equals(OptionalFieldMask, other.OptionalFieldMask)) return false;
+ if (!object.Equals(OptionalStruct, other.OptionalStruct)) return false;
+ if (!object.Equals(OptionalAny, other.OptionalAny)) return false;
+ if (!object.Equals(OptionalValue, other.OptionalValue)) return false;
+ if(!repeatedDuration_.Equals(other.repeatedDuration_)) return false;
+ if(!repeatedTimestamp_.Equals(other.repeatedTimestamp_)) return false;
+ if(!repeatedFieldmask_.Equals(other.repeatedFieldmask_)) return false;
+ if(!repeatedStruct_.Equals(other.repeatedStruct_)) return false;
+ if(!repeatedAny_.Equals(other.repeatedAny_)) return false;
+ if(!repeatedValue_.Equals(other.repeatedValue_)) return false;
+ if (Fieldname1 != other.Fieldname1) return false;
+ if (FieldName2 != other.FieldName2) return false;
+ if (FieldName3 != other.FieldName3) return false;
+ if (FieldName4 != other.FieldName4) return false;
+ if (Field0Name5 != other.Field0Name5) return false;
+ if (Field0Name6 != other.Field0Name6) return false;
+ if (FieldName7 != other.FieldName7) return false;
+ if (FieldName8 != other.FieldName8) return false;
+ if (FieldName9 != other.FieldName9) return false;
+ if (FieldName10 != other.FieldName10) return false;
+ if (FIELDNAME11 != other.FIELDNAME11) return false;
+ if (FIELDName12 != other.FIELDName12) return false;
+ if (OneofFieldCase != other.OneofFieldCase) return false;
return true;
}
@@ -1483,8 +2079,8 @@ namespace Conformance {
if (OptionalBytes.Length != 0) hash ^= OptionalBytes.GetHashCode();
if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode();
if (optionalForeignMessage_ != null) hash ^= OptionalForeignMessage.GetHashCode();
- if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) hash ^= OptionalNestedEnum.GetHashCode();
- if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) hash ^= OptionalForeignEnum.GetHashCode();
+ if (OptionalNestedEnum != 0) hash ^= OptionalNestedEnum.GetHashCode();
+ if (OptionalForeignEnum != 0) hash ^= OptionalForeignEnum.GetHashCode();
if (OptionalStringPiece.Length != 0) hash ^= OptionalStringPiece.GetHashCode();
if (OptionalCord.Length != 0) hash ^= OptionalCord.GetHashCode();
if (recursiveMessage_ != null) hash ^= RecursiveMessage.GetHashCode();
@@ -1532,11 +2128,54 @@ namespace Conformance {
if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) hash ^= OneofString.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) hash ^= OneofBytes.GetHashCode();
+ if (optionalBoolWrapper_ != null) hash ^= OptionalBoolWrapper.GetHashCode();
+ if (optionalInt32Wrapper_ != null) hash ^= OptionalInt32Wrapper.GetHashCode();
+ if (optionalInt64Wrapper_ != null) hash ^= OptionalInt64Wrapper.GetHashCode();
+ if (optionalUint32Wrapper_ != null) hash ^= OptionalUint32Wrapper.GetHashCode();
+ if (optionalUint64Wrapper_ != null) hash ^= OptionalUint64Wrapper.GetHashCode();
+ if (optionalFloatWrapper_ != null) hash ^= OptionalFloatWrapper.GetHashCode();
+ if (optionalDoubleWrapper_ != null) hash ^= OptionalDoubleWrapper.GetHashCode();
+ if (optionalStringWrapper_ != null) hash ^= OptionalStringWrapper.GetHashCode();
+ if (optionalBytesWrapper_ != null) hash ^= OptionalBytesWrapper.GetHashCode();
+ hash ^= repeatedBoolWrapper_.GetHashCode();
+ hash ^= repeatedInt32Wrapper_.GetHashCode();
+ hash ^= repeatedInt64Wrapper_.GetHashCode();
+ hash ^= repeatedUint32Wrapper_.GetHashCode();
+ hash ^= repeatedUint64Wrapper_.GetHashCode();
+ hash ^= repeatedFloatWrapper_.GetHashCode();
+ hash ^= repeatedDoubleWrapper_.GetHashCode();
+ hash ^= repeatedStringWrapper_.GetHashCode();
+ hash ^= repeatedBytesWrapper_.GetHashCode();
+ if (optionalDuration_ != null) hash ^= OptionalDuration.GetHashCode();
+ if (optionalTimestamp_ != null) hash ^= OptionalTimestamp.GetHashCode();
+ if (optionalFieldMask_ != null) hash ^= OptionalFieldMask.GetHashCode();
+ if (optionalStruct_ != null) hash ^= OptionalStruct.GetHashCode();
+ if (optionalAny_ != null) hash ^= OptionalAny.GetHashCode();
+ if (optionalValue_ != null) hash ^= OptionalValue.GetHashCode();
+ hash ^= repeatedDuration_.GetHashCode();
+ hash ^= repeatedTimestamp_.GetHashCode();
+ hash ^= repeatedFieldmask_.GetHashCode();
+ hash ^= repeatedStruct_.GetHashCode();
+ hash ^= repeatedAny_.GetHashCode();
+ hash ^= repeatedValue_.GetHashCode();
+ if (Fieldname1 != 0) hash ^= Fieldname1.GetHashCode();
+ if (FieldName2 != 0) hash ^= FieldName2.GetHashCode();
+ if (FieldName3 != 0) hash ^= FieldName3.GetHashCode();
+ if (FieldName4 != 0) hash ^= FieldName4.GetHashCode();
+ if (Field0Name5 != 0) hash ^= Field0Name5.GetHashCode();
+ if (Field0Name6 != 0) hash ^= Field0Name6.GetHashCode();
+ if (FieldName7 != 0) hash ^= FieldName7.GetHashCode();
+ if (FieldName8 != 0) hash ^= FieldName8.GetHashCode();
+ if (FieldName9 != 0) hash ^= FieldName9.GetHashCode();
+ if (FieldName10 != 0) hash ^= FieldName10.GetHashCode();
+ if (FIELDNAME11 != 0) hash ^= FIELDNAME11.GetHashCode();
+ if (FIELDName12 != 0) hash ^= FIELDName12.GetHashCode();
+ hash ^= (int) oneofFieldCase_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1608,11 +2247,11 @@ namespace Conformance {
output.WriteRawTag(154, 1);
output.WriteMessage(OptionalForeignMessage);
}
- if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
+ if (OptionalNestedEnum != 0) {
output.WriteRawTag(168, 1);
output.WriteEnum((int) OptionalNestedEnum);
}
- if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
+ if (OptionalForeignEnum != 0) {
output.WriteRawTag(176, 1);
output.WriteEnum((int) OptionalForeignEnum);
}
@@ -1684,6 +2323,120 @@ namespace Conformance {
output.WriteRawTag(146, 7);
output.WriteBytes(OneofBytes);
}
+ if (optionalBoolWrapper_ != null) {
+ _single_optionalBoolWrapper_codec.WriteTagAndValue(output, OptionalBoolWrapper);
+ }
+ if (optionalInt32Wrapper_ != null) {
+ _single_optionalInt32Wrapper_codec.WriteTagAndValue(output, OptionalInt32Wrapper);
+ }
+ if (optionalInt64Wrapper_ != null) {
+ _single_optionalInt64Wrapper_codec.WriteTagAndValue(output, OptionalInt64Wrapper);
+ }
+ if (optionalUint32Wrapper_ != null) {
+ _single_optionalUint32Wrapper_codec.WriteTagAndValue(output, OptionalUint32Wrapper);
+ }
+ if (optionalUint64Wrapper_ != null) {
+ _single_optionalUint64Wrapper_codec.WriteTagAndValue(output, OptionalUint64Wrapper);
+ }
+ if (optionalFloatWrapper_ != null) {
+ _single_optionalFloatWrapper_codec.WriteTagAndValue(output, OptionalFloatWrapper);
+ }
+ if (optionalDoubleWrapper_ != null) {
+ _single_optionalDoubleWrapper_codec.WriteTagAndValue(output, OptionalDoubleWrapper);
+ }
+ if (optionalStringWrapper_ != null) {
+ _single_optionalStringWrapper_codec.WriteTagAndValue(output, OptionalStringWrapper);
+ }
+ if (optionalBytesWrapper_ != null) {
+ _single_optionalBytesWrapper_codec.WriteTagAndValue(output, OptionalBytesWrapper);
+ }
+ repeatedBoolWrapper_.WriteTo(output, _repeated_repeatedBoolWrapper_codec);
+ repeatedInt32Wrapper_.WriteTo(output, _repeated_repeatedInt32Wrapper_codec);
+ repeatedInt64Wrapper_.WriteTo(output, _repeated_repeatedInt64Wrapper_codec);
+ repeatedUint32Wrapper_.WriteTo(output, _repeated_repeatedUint32Wrapper_codec);
+ repeatedUint64Wrapper_.WriteTo(output, _repeated_repeatedUint64Wrapper_codec);
+ repeatedFloatWrapper_.WriteTo(output, _repeated_repeatedFloatWrapper_codec);
+ repeatedDoubleWrapper_.WriteTo(output, _repeated_repeatedDoubleWrapper_codec);
+ repeatedStringWrapper_.WriteTo(output, _repeated_repeatedStringWrapper_codec);
+ repeatedBytesWrapper_.WriteTo(output, _repeated_repeatedBytesWrapper_codec);
+ if (optionalDuration_ != null) {
+ output.WriteRawTag(234, 18);
+ output.WriteMessage(OptionalDuration);
+ }
+ if (optionalTimestamp_ != null) {
+ output.WriteRawTag(242, 18);
+ output.WriteMessage(OptionalTimestamp);
+ }
+ if (optionalFieldMask_ != null) {
+ output.WriteRawTag(250, 18);
+ output.WriteMessage(OptionalFieldMask);
+ }
+ if (optionalStruct_ != null) {
+ output.WriteRawTag(130, 19);
+ output.WriteMessage(OptionalStruct);
+ }
+ if (optionalAny_ != null) {
+ output.WriteRawTag(138, 19);
+ output.WriteMessage(OptionalAny);
+ }
+ if (optionalValue_ != null) {
+ output.WriteRawTag(146, 19);
+ output.WriteMessage(OptionalValue);
+ }
+ repeatedDuration_.WriteTo(output, _repeated_repeatedDuration_codec);
+ repeatedTimestamp_.WriteTo(output, _repeated_repeatedTimestamp_codec);
+ repeatedFieldmask_.WriteTo(output, _repeated_repeatedFieldmask_codec);
+ repeatedAny_.WriteTo(output, _repeated_repeatedAny_codec);
+ repeatedValue_.WriteTo(output, _repeated_repeatedValue_codec);
+ repeatedStruct_.WriteTo(output, _repeated_repeatedStruct_codec);
+ if (Fieldname1 != 0) {
+ output.WriteRawTag(136, 25);
+ output.WriteInt32(Fieldname1);
+ }
+ if (FieldName2 != 0) {
+ output.WriteRawTag(144, 25);
+ output.WriteInt32(FieldName2);
+ }
+ if (FieldName3 != 0) {
+ output.WriteRawTag(152, 25);
+ output.WriteInt32(FieldName3);
+ }
+ if (FieldName4 != 0) {
+ output.WriteRawTag(160, 25);
+ output.WriteInt32(FieldName4);
+ }
+ if (Field0Name5 != 0) {
+ output.WriteRawTag(168, 25);
+ output.WriteInt32(Field0Name5);
+ }
+ if (Field0Name6 != 0) {
+ output.WriteRawTag(176, 25);
+ output.WriteInt32(Field0Name6);
+ }
+ if (FieldName7 != 0) {
+ output.WriteRawTag(184, 25);
+ output.WriteInt32(FieldName7);
+ }
+ if (FieldName8 != 0) {
+ output.WriteRawTag(192, 25);
+ output.WriteInt32(FieldName8);
+ }
+ if (FieldName9 != 0) {
+ output.WriteRawTag(200, 25);
+ output.WriteInt32(FieldName9);
+ }
+ if (FieldName10 != 0) {
+ output.WriteRawTag(208, 25);
+ output.WriteInt32(FieldName10);
+ }
+ if (FIELDNAME11 != 0) {
+ output.WriteRawTag(216, 25);
+ output.WriteInt32(FIELDNAME11);
+ }
+ if (FIELDName12 != 0) {
+ output.WriteRawTag(224, 25);
+ output.WriteInt32(FIELDName12);
+ }
}
public int CalculateSize() {
@@ -1739,10 +2492,10 @@ namespace Conformance {
if (optionalForeignMessage_ != null) {
size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalForeignMessage);
}
- if (OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
+ if (OptionalNestedEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum);
}
- if (OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
+ if (OptionalForeignEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalForeignEnum);
}
if (OptionalStringPiece.Length != 0) {
@@ -1806,6 +2559,102 @@ namespace Conformance {
if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) {
size += 2 + pb::CodedOutputStream.ComputeBytesSize(OneofBytes);
}
+ if (optionalBoolWrapper_ != null) {
+ size += _single_optionalBoolWrapper_codec.CalculateSizeWithTag(OptionalBoolWrapper);
+ }
+ if (optionalInt32Wrapper_ != null) {
+ size += _single_optionalInt32Wrapper_codec.CalculateSizeWithTag(OptionalInt32Wrapper);
+ }
+ if (optionalInt64Wrapper_ != null) {
+ size += _single_optionalInt64Wrapper_codec.CalculateSizeWithTag(OptionalInt64Wrapper);
+ }
+ if (optionalUint32Wrapper_ != null) {
+ size += _single_optionalUint32Wrapper_codec.CalculateSizeWithTag(OptionalUint32Wrapper);
+ }
+ if (optionalUint64Wrapper_ != null) {
+ size += _single_optionalUint64Wrapper_codec.CalculateSizeWithTag(OptionalUint64Wrapper);
+ }
+ if (optionalFloatWrapper_ != null) {
+ size += _single_optionalFloatWrapper_codec.CalculateSizeWithTag(OptionalFloatWrapper);
+ }
+ if (optionalDoubleWrapper_ != null) {
+ size += _single_optionalDoubleWrapper_codec.CalculateSizeWithTag(OptionalDoubleWrapper);
+ }
+ if (optionalStringWrapper_ != null) {
+ size += _single_optionalStringWrapper_codec.CalculateSizeWithTag(OptionalStringWrapper);
+ }
+ if (optionalBytesWrapper_ != null) {
+ size += _single_optionalBytesWrapper_codec.CalculateSizeWithTag(OptionalBytesWrapper);
+ }
+ size += repeatedBoolWrapper_.CalculateSize(_repeated_repeatedBoolWrapper_codec);
+ size += repeatedInt32Wrapper_.CalculateSize(_repeated_repeatedInt32Wrapper_codec);
+ size += repeatedInt64Wrapper_.CalculateSize(_repeated_repeatedInt64Wrapper_codec);
+ size += repeatedUint32Wrapper_.CalculateSize(_repeated_repeatedUint32Wrapper_codec);
+ size += repeatedUint64Wrapper_.CalculateSize(_repeated_repeatedUint64Wrapper_codec);
+ size += repeatedFloatWrapper_.CalculateSize(_repeated_repeatedFloatWrapper_codec);
+ size += repeatedDoubleWrapper_.CalculateSize(_repeated_repeatedDoubleWrapper_codec);
+ size += repeatedStringWrapper_.CalculateSize(_repeated_repeatedStringWrapper_codec);
+ size += repeatedBytesWrapper_.CalculateSize(_repeated_repeatedBytesWrapper_codec);
+ if (optionalDuration_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalDuration);
+ }
+ if (optionalTimestamp_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalTimestamp);
+ }
+ if (optionalFieldMask_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalFieldMask);
+ }
+ if (optionalStruct_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalStruct);
+ }
+ if (optionalAny_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalAny);
+ }
+ if (optionalValue_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalValue);
+ }
+ size += repeatedDuration_.CalculateSize(_repeated_repeatedDuration_codec);
+ size += repeatedTimestamp_.CalculateSize(_repeated_repeatedTimestamp_codec);
+ size += repeatedFieldmask_.CalculateSize(_repeated_repeatedFieldmask_codec);
+ size += repeatedStruct_.CalculateSize(_repeated_repeatedStruct_codec);
+ size += repeatedAny_.CalculateSize(_repeated_repeatedAny_codec);
+ size += repeatedValue_.CalculateSize(_repeated_repeatedValue_codec);
+ if (Fieldname1 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(Fieldname1);
+ }
+ if (FieldName2 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName2);
+ }
+ if (FieldName3 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName3);
+ }
+ if (FieldName4 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName4);
+ }
+ if (Field0Name5 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name5);
+ }
+ if (Field0Name6 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(Field0Name6);
+ }
+ if (FieldName7 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName7);
+ }
+ if (FieldName8 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName8);
+ }
+ if (FieldName9 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName9);
+ }
+ if (FieldName10 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FieldName10);
+ }
+ if (FIELDNAME11 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDNAME11);
+ }
+ if (FIELDName12 != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(FIELDName12);
+ }
return size;
}
@@ -1870,10 +2719,10 @@ namespace Conformance {
}
OptionalForeignMessage.MergeFrom(other.OptionalForeignMessage);
}
- if (other.OptionalNestedEnum != global::Conformance.TestAllTypes.Types.NestedEnum.FOO) {
+ if (other.OptionalNestedEnum != 0) {
OptionalNestedEnum = other.OptionalNestedEnum;
}
- if (other.OptionalForeignEnum != global::Conformance.ForeignEnum.FOREIGN_FOO) {
+ if (other.OptionalForeignEnum != 0) {
OptionalForeignEnum = other.OptionalForeignEnum;
}
if (other.OptionalStringPiece.Length != 0) {
@@ -1928,6 +2777,138 @@ namespace Conformance {
mapStringForeignMessage_.Add(other.mapStringForeignMessage_);
mapStringNestedEnum_.Add(other.mapStringNestedEnum_);
mapStringForeignEnum_.Add(other.mapStringForeignEnum_);
+ if (other.optionalBoolWrapper_ != null) {
+ if (optionalBoolWrapper_ == null || other.OptionalBoolWrapper != false) {
+ OptionalBoolWrapper = other.OptionalBoolWrapper;
+ }
+ }
+ if (other.optionalInt32Wrapper_ != null) {
+ if (optionalInt32Wrapper_ == null || other.OptionalInt32Wrapper != 0) {
+ OptionalInt32Wrapper = other.OptionalInt32Wrapper;
+ }
+ }
+ if (other.optionalInt64Wrapper_ != null) {
+ if (optionalInt64Wrapper_ == null || other.OptionalInt64Wrapper != 0L) {
+ OptionalInt64Wrapper = other.OptionalInt64Wrapper;
+ }
+ }
+ if (other.optionalUint32Wrapper_ != null) {
+ if (optionalUint32Wrapper_ == null || other.OptionalUint32Wrapper != 0) {
+ OptionalUint32Wrapper = other.OptionalUint32Wrapper;
+ }
+ }
+ if (other.optionalUint64Wrapper_ != null) {
+ if (optionalUint64Wrapper_ == null || other.OptionalUint64Wrapper != 0UL) {
+ OptionalUint64Wrapper = other.OptionalUint64Wrapper;
+ }
+ }
+ if (other.optionalFloatWrapper_ != null) {
+ if (optionalFloatWrapper_ == null || other.OptionalFloatWrapper != 0F) {
+ OptionalFloatWrapper = other.OptionalFloatWrapper;
+ }
+ }
+ if (other.optionalDoubleWrapper_ != null) {
+ if (optionalDoubleWrapper_ == null || other.OptionalDoubleWrapper != 0D) {
+ OptionalDoubleWrapper = other.OptionalDoubleWrapper;
+ }
+ }
+ if (other.optionalStringWrapper_ != null) {
+ if (optionalStringWrapper_ == null || other.OptionalStringWrapper != "") {
+ OptionalStringWrapper = other.OptionalStringWrapper;
+ }
+ }
+ if (other.optionalBytesWrapper_ != null) {
+ if (optionalBytesWrapper_ == null || other.OptionalBytesWrapper != pb::ByteString.Empty) {
+ OptionalBytesWrapper = other.OptionalBytesWrapper;
+ }
+ }
+ repeatedBoolWrapper_.Add(other.repeatedBoolWrapper_);
+ repeatedInt32Wrapper_.Add(other.repeatedInt32Wrapper_);
+ repeatedInt64Wrapper_.Add(other.repeatedInt64Wrapper_);
+ repeatedUint32Wrapper_.Add(other.repeatedUint32Wrapper_);
+ repeatedUint64Wrapper_.Add(other.repeatedUint64Wrapper_);
+ repeatedFloatWrapper_.Add(other.repeatedFloatWrapper_);
+ repeatedDoubleWrapper_.Add(other.repeatedDoubleWrapper_);
+ repeatedStringWrapper_.Add(other.repeatedStringWrapper_);
+ repeatedBytesWrapper_.Add(other.repeatedBytesWrapper_);
+ if (other.optionalDuration_ != null) {
+ if (optionalDuration_ == null) {
+ optionalDuration_ = new global::Google.Protobuf.WellKnownTypes.Duration();
+ }
+ OptionalDuration.MergeFrom(other.OptionalDuration);
+ }
+ if (other.optionalTimestamp_ != null) {
+ if (optionalTimestamp_ == null) {
+ optionalTimestamp_ = new global::Google.Protobuf.WellKnownTypes.Timestamp();
+ }
+ OptionalTimestamp.MergeFrom(other.OptionalTimestamp);
+ }
+ if (other.optionalFieldMask_ != null) {
+ if (optionalFieldMask_ == null) {
+ optionalFieldMask_ = new global::Google.Protobuf.WellKnownTypes.FieldMask();
+ }
+ OptionalFieldMask.MergeFrom(other.OptionalFieldMask);
+ }
+ if (other.optionalStruct_ != null) {
+ if (optionalStruct_ == null) {
+ optionalStruct_ = new global::Google.Protobuf.WellKnownTypes.Struct();
+ }
+ OptionalStruct.MergeFrom(other.OptionalStruct);
+ }
+ if (other.optionalAny_ != null) {
+ if (optionalAny_ == null) {
+ optionalAny_ = new global::Google.Protobuf.WellKnownTypes.Any();
+ }
+ OptionalAny.MergeFrom(other.OptionalAny);
+ }
+ if (other.optionalValue_ != null) {
+ if (optionalValue_ == null) {
+ optionalValue_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ OptionalValue.MergeFrom(other.OptionalValue);
+ }
+ repeatedDuration_.Add(other.repeatedDuration_);
+ repeatedTimestamp_.Add(other.repeatedTimestamp_);
+ repeatedFieldmask_.Add(other.repeatedFieldmask_);
+ repeatedStruct_.Add(other.repeatedStruct_);
+ repeatedAny_.Add(other.repeatedAny_);
+ repeatedValue_.Add(other.repeatedValue_);
+ if (other.Fieldname1 != 0) {
+ Fieldname1 = other.Fieldname1;
+ }
+ if (other.FieldName2 != 0) {
+ FieldName2 = other.FieldName2;
+ }
+ if (other.FieldName3 != 0) {
+ FieldName3 = other.FieldName3;
+ }
+ if (other.FieldName4 != 0) {
+ FieldName4 = other.FieldName4;
+ }
+ if (other.Field0Name5 != 0) {
+ Field0Name5 = other.Field0Name5;
+ }
+ if (other.Field0Name6 != 0) {
+ Field0Name6 = other.Field0Name6;
+ }
+ if (other.FieldName7 != 0) {
+ FieldName7 = other.FieldName7;
+ }
+ if (other.FieldName8 != 0) {
+ FieldName8 = other.FieldName8;
+ }
+ if (other.FieldName9 != 0) {
+ FieldName9 = other.FieldName9;
+ }
+ if (other.FieldName10 != 0) {
+ FieldName10 = other.FieldName10;
+ }
+ if (other.FIELDNAME11 != 0) {
+ FIELDNAME11 = other.FIELDNAME11;
+ }
+ if (other.FIELDName12 != 0) {
+ FIELDName12 = other.FIELDName12;
+ }
switch (other.OneofFieldCase) {
case OneofFieldOneofCase.OneofUint32:
OneofUint32 = other.OneofUint32;
@@ -2245,6 +3226,219 @@ namespace Conformance {
OneofBytes = input.ReadBytes();
break;
}
+ case 1610: {
+ bool? value = _single_optionalBoolWrapper_codec.Read(input);
+ if (optionalBoolWrapper_ == null || value != false) {
+ OptionalBoolWrapper = value;
+ }
+ break;
+ }
+ case 1618: {
+ int? value = _single_optionalInt32Wrapper_codec.Read(input);
+ if (optionalInt32Wrapper_ == null || value != 0) {
+ OptionalInt32Wrapper = value;
+ }
+ break;
+ }
+ case 1626: {
+ long? value = _single_optionalInt64Wrapper_codec.Read(input);
+ if (optionalInt64Wrapper_ == null || value != 0L) {
+ OptionalInt64Wrapper = value;
+ }
+ break;
+ }
+ case 1634: {
+ uint? value = _single_optionalUint32Wrapper_codec.Read(input);
+ if (optionalUint32Wrapper_ == null || value != 0) {
+ OptionalUint32Wrapper = value;
+ }
+ break;
+ }
+ case 1642: {
+ ulong? value = _single_optionalUint64Wrapper_codec.Read(input);
+ if (optionalUint64Wrapper_ == null || value != 0UL) {
+ OptionalUint64Wrapper = value;
+ }
+ break;
+ }
+ case 1650: {
+ float? value = _single_optionalFloatWrapper_codec.Read(input);
+ if (optionalFloatWrapper_ == null || value != 0F) {
+ OptionalFloatWrapper = value;
+ }
+ break;
+ }
+ case 1658: {
+ double? value = _single_optionalDoubleWrapper_codec.Read(input);
+ if (optionalDoubleWrapper_ == null || value != 0D) {
+ OptionalDoubleWrapper = value;
+ }
+ break;
+ }
+ case 1666: {
+ string value = _single_optionalStringWrapper_codec.Read(input);
+ if (optionalStringWrapper_ == null || value != "") {
+ OptionalStringWrapper = value;
+ }
+ break;
+ }
+ case 1674: {
+ pb::ByteString value = _single_optionalBytesWrapper_codec.Read(input);
+ if (optionalBytesWrapper_ == null || value != pb::ByteString.Empty) {
+ OptionalBytesWrapper = value;
+ }
+ break;
+ }
+ case 1690: {
+ repeatedBoolWrapper_.AddEntriesFrom(input, _repeated_repeatedBoolWrapper_codec);
+ break;
+ }
+ case 1698: {
+ repeatedInt32Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt32Wrapper_codec);
+ break;
+ }
+ case 1706: {
+ repeatedInt64Wrapper_.AddEntriesFrom(input, _repeated_repeatedInt64Wrapper_codec);
+ break;
+ }
+ case 1714: {
+ repeatedUint32Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint32Wrapper_codec);
+ break;
+ }
+ case 1722: {
+ repeatedUint64Wrapper_.AddEntriesFrom(input, _repeated_repeatedUint64Wrapper_codec);
+ break;
+ }
+ case 1730: {
+ repeatedFloatWrapper_.AddEntriesFrom(input, _repeated_repeatedFloatWrapper_codec);
+ break;
+ }
+ case 1738: {
+ repeatedDoubleWrapper_.AddEntriesFrom(input, _repeated_repeatedDoubleWrapper_codec);
+ break;
+ }
+ case 1746: {
+ repeatedStringWrapper_.AddEntriesFrom(input, _repeated_repeatedStringWrapper_codec);
+ break;
+ }
+ case 1754: {
+ repeatedBytesWrapper_.AddEntriesFrom(input, _repeated_repeatedBytesWrapper_codec);
+ break;
+ }
+ case 2410: {
+ if (optionalDuration_ == null) {
+ optionalDuration_ = new global::Google.Protobuf.WellKnownTypes.Duration();
+ }
+ input.ReadMessage(optionalDuration_);
+ break;
+ }
+ case 2418: {
+ if (optionalTimestamp_ == null) {
+ optionalTimestamp_ = new global::Google.Protobuf.WellKnownTypes.Timestamp();
+ }
+ input.ReadMessage(optionalTimestamp_);
+ break;
+ }
+ case 2426: {
+ if (optionalFieldMask_ == null) {
+ optionalFieldMask_ = new global::Google.Protobuf.WellKnownTypes.FieldMask();
+ }
+ input.ReadMessage(optionalFieldMask_);
+ break;
+ }
+ case 2434: {
+ if (optionalStruct_ == null) {
+ optionalStruct_ = new global::Google.Protobuf.WellKnownTypes.Struct();
+ }
+ input.ReadMessage(optionalStruct_);
+ break;
+ }
+ case 2442: {
+ if (optionalAny_ == null) {
+ optionalAny_ = new global::Google.Protobuf.WellKnownTypes.Any();
+ }
+ input.ReadMessage(optionalAny_);
+ break;
+ }
+ case 2450: {
+ if (optionalValue_ == null) {
+ optionalValue_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ input.ReadMessage(optionalValue_);
+ break;
+ }
+ case 2490: {
+ repeatedDuration_.AddEntriesFrom(input, _repeated_repeatedDuration_codec);
+ break;
+ }
+ case 2498: {
+ repeatedTimestamp_.AddEntriesFrom(input, _repeated_repeatedTimestamp_codec);
+ break;
+ }
+ case 2506: {
+ repeatedFieldmask_.AddEntriesFrom(input, _repeated_repeatedFieldmask_codec);
+ break;
+ }
+ case 2522: {
+ repeatedAny_.AddEntriesFrom(input, _repeated_repeatedAny_codec);
+ break;
+ }
+ case 2530: {
+ repeatedValue_.AddEntriesFrom(input, _repeated_repeatedValue_codec);
+ break;
+ }
+ case 2594: {
+ repeatedStruct_.AddEntriesFrom(input, _repeated_repeatedStruct_codec);
+ break;
+ }
+ case 3208: {
+ Fieldname1 = input.ReadInt32();
+ break;
+ }
+ case 3216: {
+ FieldName2 = input.ReadInt32();
+ break;
+ }
+ case 3224: {
+ FieldName3 = input.ReadInt32();
+ break;
+ }
+ case 3232: {
+ FieldName4 = input.ReadInt32();
+ break;
+ }
+ case 3240: {
+ Field0Name5 = input.ReadInt32();
+ break;
+ }
+ case 3248: {
+ Field0Name6 = input.ReadInt32();
+ break;
+ }
+ case 3256: {
+ FieldName7 = input.ReadInt32();
+ break;
+ }
+ case 3264: {
+ FieldName8 = input.ReadInt32();
+ break;
+ }
+ case 3272: {
+ FieldName9 = input.ReadInt32();
+ break;
+ }
+ case 3280: {
+ FieldName10 = input.ReadInt32();
+ break;
+ }
+ case 3288: {
+ FIELDNAME11 = input.ReadInt32();
+ break;
+ }
+ case 3296: {
+ FIELDName12 = input.ReadInt32();
+ break;
+ }
}
}
}
@@ -2254,13 +3448,13 @@ namespace Conformance {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class Types {
public enum NestedEnum {
- FOO = 0,
- BAR = 1,
- BAZ = 2,
+ [pbr::OriginalName("FOO")] Foo = 0,
+ [pbr::OriginalName("BAR")] Bar = 1,
+ [pbr::OriginalName("BAZ")] Baz = 2,
/// <summary>
/// Intentionally negative.
/// </summary>
- NEG = -1,
+ [pbr::OriginalName("NEG")] Neg = -1,
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -2335,7 +3529,7 @@ namespace Conformance {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2410,7 +3604,7 @@ namespace Conformance {
public static pb::MessageParser<ForeignMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Conformance.Conformance.Descriptor.MessageTypes[3]; }
+ get { return global::Conformance.ConformanceReflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2463,7 +3657,7 @@ namespace Conformance {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf.Conformance/Program.cs b/csharp/src/Google.Protobuf.Conformance/Program.cs
index af92da9f..19827c48 100644
--- a/csharp/src/Google.Protobuf.Conformance/Program.cs
+++ b/csharp/src/Google.Protobuf.Conformance/Program.cs
@@ -31,6 +31,7 @@
#endregion
using Conformance;
+using Google.Protobuf.Reflection;
using System;
using System.IO;
@@ -47,16 +48,17 @@ 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(TestAllTypes.Descriptor);
int count = 0;
- while (RunTest(input, output))
+ while (RunTest(input, output, typeRegistry))
{
count++;
}
Console.Error.WriteLine("Received EOF after {0} tests", count);
}
- private static bool RunTest(BinaryReader input, BinaryWriter output)
+ private static bool RunTest(BinaryReader input, BinaryWriter output, TypeRegistry typeRegistry)
{
int? size = ReadInt32(input);
if (size == null)
@@ -69,7 +71,7 @@ namespace Google.Protobuf.Conformance
throw new EndOfStreamException("Read " + inputData.Length + " bytes of data when expecting " + size);
}
ConformanceRequest request = ConformanceRequest.Parser.ParseFrom(inputData);
- ConformanceResponse response = PerformRequest(request);
+ ConformanceResponse response = PerformRequest(request, typeRegistry);
byte[] outputData = response.ToByteArray();
output.Write(outputData.Length);
output.Write(outputData);
@@ -77,34 +79,48 @@ namespace Google.Protobuf.Conformance
return true;
}
- private static ConformanceResponse PerformRequest(ConformanceRequest request)
+ private static ConformanceResponse PerformRequest(ConformanceRequest request, TypeRegistry typeRegistry)
{
TestAllTypes message;
- switch (request.PayloadCase)
+ try
{
- case ConformanceRequest.PayloadOneofCase.JsonPayload:
- return new ConformanceResponse { Skipped = "JSON parsing not implemented in C# yet" };
- case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
- try
- {
+ switch (request.PayloadCase)
+ {
+ case ConformanceRequest.PayloadOneofCase.JsonPayload:
+ var parser = new JsonParser(new JsonParser.Settings(20, typeRegistry));
+ message = parser.Parse<TestAllTypes>(request.JsonPayload);
+ break;
+ case ConformanceRequest.PayloadOneofCase.ProtobufPayload:
message = TestAllTypes.Parser.ParseFrom(request.ProtobufPayload);
- }
- catch (InvalidProtocolBufferException e)
- {
- return new ConformanceResponse { ParseError = e.Message };
- }
- break;
- default:
- throw new Exception("Unsupported request payload: " + request.PayloadCase);
+ break;
+ default:
+ throw new Exception("Unsupported request payload: " + request.PayloadCase);
+ }
}
- switch (request.RequestedOutputFormat)
+ catch (InvalidProtocolBufferException e)
{
- case global::Conformance.WireFormat.JSON:
- return new ConformanceResponse { JsonPayload = JsonFormatter.Default.Format(message) };
- case global::Conformance.WireFormat.PROTOBUF:
- return new ConformanceResponse { ProtobufPayload = message.ToByteString() };
- default:
- throw new Exception("Unsupported request output format: " + request.PayloadCase);
+ return new ConformanceResponse { ParseError = e.Message };
+ }
+ catch (InvalidJsonException e)
+ {
+ return new ConformanceResponse { ParseError = e.Message };
+ }
+ try
+ {
+ switch (request.RequestedOutputFormat)
+ {
+ case global::Conformance.WireFormat.Json:
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, typeRegistry));
+ return new ConformanceResponse { JsonPayload = formatter.Format(message) };
+ case global::Conformance.WireFormat.Protobuf:
+ return new ConformanceResponse { ProtobufPayload = message.ToByteString() };
+ default:
+ throw new Exception("Unsupported request output format: " + request.PayloadCase);
+ }
+ }
+ catch (InvalidOperationException e)
+ {
+ return new ConformanceResponse { SerializeError = e.Message };
}
}
diff --git a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
index 54c44e47..c0a9ffd1 100644
--- a/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedInputStreamTest.cs
@@ -284,7 +284,7 @@ namespace Google.Protobuf
Assert.Throws<InvalidProtocolBufferException>(() => input.ReadBytes());
}
- private static TestRecursiveMessage MakeRecursiveMessage(int depth)
+ internal static TestRecursiveMessage MakeRecursiveMessage(int depth)
{
if (depth == 0)
{
@@ -296,7 +296,7 @@ namespace Google.Protobuf
}
}
- private static void AssertMessageDepth(TestRecursiveMessage message, int depth)
+ internal static void AssertMessageDepth(TestRecursiveMessage message, int depth)
{
if (depth == 0)
{
@@ -470,6 +470,52 @@ namespace Google.Protobuf
}
[Test]
+ public void SkipGroup_WrongEndGroupTag()
+ {
+ // Create an output stream with:
+ // Field 1: string "field 1"
+ // Start group 2
+ // Field 3: fixed int32
+ // End group 4 (should give an error)
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.LengthDelimited);
+ output.WriteString("field 1");
+
+ // The outer group...
+ output.WriteTag(2, WireFormat.WireType.StartGroup);
+ output.WriteTag(3, WireFormat.WireType.Fixed32);
+ output.WriteFixed32(100);
+ output.WriteTag(4, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ // Now act like a generated client
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited), input.ReadTag());
+ Assert.AreEqual("field 1", input.ReadString());
+ Assert.AreEqual(WireFormat.MakeTag(2, WireFormat.WireType.StartGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
+ public void RogueEndGroupTag()
+ {
+ // If we have an end-group tag without a leading start-group tag, generated
+ // code will just call SkipLastField... so that should fail.
+
+ var stream = new MemoryStream();
+ var output = new CodedOutputStream(stream);
+ output.WriteTag(1, WireFormat.WireType.EndGroup);
+ output.Flush();
+ stream.Position = 0;
+
+ var input = new CodedInputStream(stream);
+ Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.EndGroup), input.ReadTag());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
+ }
+
+ [Test]
public void EndOfStreamReachedWhileSkippingGroup()
{
var stream = new MemoryStream();
@@ -484,7 +530,7 @@ namespace Google.Protobuf
// Now act like a generated client
var input = new CodedInputStream(stream);
input.ReadTag();
- Assert.Throws<InvalidProtocolBufferException>(() => input.SkipLastField());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
@@ -506,7 +552,7 @@ namespace Google.Protobuf
// Now act like a generated client
var input = new CodedInputStream(stream);
Assert.AreEqual(WireFormat.MakeTag(1, WireFormat.WireType.StartGroup), input.ReadTag());
- Assert.Throws<InvalidProtocolBufferException>(() => input.SkipLastField());
+ Assert.Throws<InvalidProtocolBufferException>(input.SkipLastField);
}
[Test]
@@ -526,5 +572,27 @@ namespace Google.Protobuf
Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 0, 1));
Assert.Throws<ArgumentOutOfRangeException>(() => CodedInputStream.CreateWithLimits(stream, 1, 0));
}
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream))
+ {
+ }
+ Assert.IsFalse(memoryStream.CanRead); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanRead);
+ using (var cis = new CodedInputStream(memoryStream, true))
+ {
+ }
+ Assert.IsTrue(memoryStream.CanRead); // We left the stream open
+ }
}
} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
index 3297fe87..48bf6d60 100644
--- a/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
+++ b/csharp/src/Google.Protobuf.Test/CodedOutputStreamTest.cs
@@ -387,5 +387,33 @@ namespace Google.Protobuf
Assert.IsTrue(cin.IsAtEnd);
}
}
+
+ [Test]
+ public void Dispose_DisposesUnderlyingStream()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.ToArray().Length); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsFalse(memoryStream.CanWrite); // Disposed
+ }
+
+ [Test]
+ public void Dispose_WithLeaveOpen()
+ {
+ var memoryStream = new MemoryStream();
+ Assert.IsTrue(memoryStream.CanWrite);
+ using (var cos = new CodedOutputStream(memoryStream, true))
+ {
+ cos.WriteRawByte(0);
+ Assert.AreEqual(0, memoryStream.Position); // Not flushed yet
+ }
+ Assert.AreEqual(1, memoryStream.Position); // Flushed data from CodedOutputStream to MemoryStream
+ Assert.IsTrue(memoryStream.CanWrite); // We left the stream open
+ }
}
} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
index ba82c0e8..9c845907 100644
--- a/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Collections/MapFieldTest.cs
@@ -56,7 +56,7 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void NullValues()
+ public void NullValuesProhibited()
{
TestNullValues<int?>(0);
TestNullValues("");
@@ -65,19 +65,12 @@ namespace Google.Protobuf.Collections
private void TestNullValues<T>(T nonNullValue)
{
- var map = new MapField<int, T>(false);
+ var map = new MapField<int, T>();
var nullValue = (T) (object) null;
Assert.Throws<ArgumentNullException>(() => map.Add(0, nullValue));
Assert.Throws<ArgumentNullException>(() => map[0] = nullValue);
map.Add(1, nonNullValue);
map[1] = nonNullValue;
-
- // Doesn't throw...
- map = new MapField<int, T>(true);
- map.Add(0, nullValue);
- map[0] = nullValue;
- map.Add(1, nonNullValue);
- map[1] = nonNullValue;
}
[Test]
@@ -161,27 +154,6 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void EqualityHandlesNullValues()
- {
- var map1 = new MapField<string, ForeignMessage>();
- map1.Add("a", new ForeignMessage { C = 10 });
- map1.Add("b", null);
-
- var map2 = new MapField<string, ForeignMessage>();
- map2.Add("a", new ForeignMessage { C = 10 });
- map2.Add("b", null);
-
- EqualityTester.AssertEquality(map1, map2);
- // Check the null value isn't ignored entirely...
- Assert.IsTrue(map1.Remove("b"));
- EqualityTester.AssertInequality(map1, map2);
- map1.Add("b", new ForeignMessage());
- EqualityTester.AssertInequality(map1, map2);
- map1["b"] = null;
- EqualityTester.AssertEquality(map1, map2);
- }
-
- [Test]
public void Add_Dictionary()
{
var map1 = new MapField<string, string>
@@ -454,30 +426,6 @@ namespace Google.Protobuf.Collections
}
[Test]
- public void AllowNullValues_Property()
- {
- // Non-message reference type values are non-nullable by default, but can be overridden
- Assert.IsFalse(new MapField<int, string>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, string>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, string>(true).AllowsNullValues);
-
- // Non-nullable value type values are never nullable
- Assert.IsFalse(new MapField<int, int>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, int>(false).AllowsNullValues);
- Assert.Throws<ArgumentException>(() => new MapField<int, int>(true));
-
- // Message type values are nullable by default, but can be overridden
- Assert.IsTrue(new MapField<int, TestAllTypes>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, TestAllTypes>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, TestAllTypes>(true).AllowsNullValues);
-
- // Nullable value type values are nullable by default, but can be overridden
- Assert.IsTrue(new MapField<int, int?>().AllowsNullValues);
- Assert.IsFalse(new MapField<int, int?>(false).AllowsNullValues);
- Assert.IsTrue(new MapField<int, int?>(true).AllowsNullValues);
- }
-
- [Test]
public void KeysReturnsLiveView()
{
var map = new MapField<string, string>();
diff --git a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
index 38ba227f..c616470e 100644
--- a/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
+++ b/csharp/src/Google.Protobuf.Test/FieldCodecTest.cs
@@ -58,7 +58,7 @@ namespace Google.Protobuf
new FieldCodecTestData<float>(FieldCodec.ForFloat(100), 1234.5f, "Float"),
new FieldCodecTestData<double>(FieldCodec.ForDouble(100), 1234567890.5d, "Double"),
new FieldCodecTestData<ForeignEnum>(
- FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.FOREIGN_BAZ, "Enum"),
+ FieldCodec.ForEnum(100, t => (int) t, t => (ForeignEnum) t), ForeignEnum.ForeignBaz, "Enum"),
new FieldCodecTestData<ForeignMessage>(
FieldCodec.ForMessage(100, ForeignMessage.Parser), new ForeignMessage { C = 10 }, "Message"),
};
diff --git a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
index 575d4586..8b153d69 100644
--- a/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
+++ b/csharp/src/Google.Protobuf.Test/GeneratedMessageTest.cs
@@ -66,13 +66,13 @@ namespace Google.Protobuf
Assert.AreEqual(0, message.SingleFixed32);
Assert.AreEqual(0L, message.SingleFixed64);
Assert.AreEqual(0.0f, message.SingleFloat);
- Assert.AreEqual(ForeignEnum.FOREIGN_UNSPECIFIED, message.SingleForeignEnum);
+ Assert.AreEqual(ForeignEnum.ForeignUnspecified, message.SingleForeignEnum);
Assert.IsNull(message.SingleForeignMessage);
- Assert.AreEqual(ImportEnum.IMPORT_ENUM_UNSPECIFIED, message.SingleImportEnum);
+ Assert.AreEqual(ImportEnum.Unspecified, message.SingleImportEnum);
Assert.IsNull(message.SingleImportMessage);
Assert.AreEqual(0, message.SingleInt32);
Assert.AreEqual(0L, message.SingleInt64);
- Assert.AreEqual(TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED, message.SingleNestedEnum);
+ Assert.AreEqual(TestAllTypes.Types.NestedEnum.Unspecified, message.SingleNestedEnum);
Assert.IsNull(message.SingleNestedMessage);
Assert.IsNull(message.SinglePublicImportMessage);
Assert.AreEqual(0, message.SingleSfixed32);
@@ -145,13 +145,13 @@ namespace Google.Protobuf
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.IMPORT_BAZ,
+ SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
@@ -179,13 +179,13 @@ namespace Google.Protobuf
RepeatedFixed32 = { uint.MaxValue, 23 },
RepeatedFixed64 = { ulong.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
- RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
+ RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
- RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
+ RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
RepeatedImportMessage = { new ImportMessage { D = 20 }, new ImportMessage { D = 25 } },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
- RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, 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 },
@@ -221,11 +221,11 @@ namespace Google.Protobuf
},
MapInt32ForeignMessage = {
{ 0, new ForeignMessage { C = 10 } },
- { 5, null },
+ { 5, new ForeignMessage() },
},
MapInt32Enum = {
- { 1, MapEnum.MAP_ENUM_BAR },
- { 2000, MapEnum.MAP_ENUM_FOO }
+ { 1, MapEnum.Bar },
+ { 2000, MapEnum.Foo }
}
};
@@ -249,7 +249,7 @@ namespace Google.Protobuf
Assert.AreEqual(1, parsed.MapInt32Bytes.Count);
Assert.AreEqual(ByteString.Empty, parsed.MapInt32Bytes[0]);
}
-
+
[Test]
public void MapWithOnlyValue()
{
@@ -269,6 +269,40 @@ namespace Google.Protobuf
}
[Test]
+ public void MapWithOnlyKey_PrimitiveValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32DoubleFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(0.0, parsed.MapInt32Double[key]);
+ }
+
+ [Test]
+ public void MapWithOnlyKey_MessageValue()
+ {
+ // Hand-craft the stream to contain a single entry with just a key.
+ var memoryStream = new MemoryStream();
+ var output = new CodedOutputStream(memoryStream);
+ output.WriteTag(TestMap.MapInt32ForeignMessageFieldNumber, WireFormat.WireType.LengthDelimited);
+ int key = 10;
+ output.WriteLength(1 + CodedOutputStream.ComputeInt32Size(key));
+ output.WriteTag(1, WireFormat.WireType.Varint);
+ output.WriteInt32(key);
+ output.Flush();
+
+ var parsed = TestMap.Parser.ParseFrom(memoryStream.ToArray());
+ Assert.AreEqual(new ForeignMessage(), parsed.MapInt32ForeignMessage[key]);
+ }
+
+ [Test]
public void MapIgnoresExtraFieldsWithinEntryMessages()
{
// Hand-craft the stream to contain a single entry with three fields
@@ -415,7 +449,7 @@ namespace Google.Protobuf
SingleFloat = 12.25f,
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleSfixed32 = -123,
SingleSfixed64 = -12345678901234,
SingleSint32 = -456,
@@ -445,7 +479,7 @@ namespace Google.Protobuf
RepeatedFloat = { 100f, 12.25f },
RepeatedInt32 = { 100, 200 },
RepeatedInt64 = { 3210987654321, long.MaxValue },
- RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.FOO, TestAllTypes.Types.NestedEnum.NEG },
+ RepeatedNestedEnum = { TestAllTypes.Types.NestedEnum.Foo, TestAllTypes.Types.NestedEnum.Neg },
RepeatedSfixed32 = { -123, 123 },
RepeatedSfixed64 = { -12345678901234, 12345678901234 },
RepeatedSint32 = { -456, 100 },
@@ -566,6 +600,16 @@ namespace Google.Protobuf
}
[Test]
+ public void Oneof_DefaultValuesNotEqual()
+ {
+ var message1 = new TestAllTypes { OneofString = "" };
+ var message2 = new TestAllTypes { OneofUint32 = 0 };
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofString, message1.OneofFieldCase);
+ Assert.AreEqual(TestAllTypes.OneofFieldOneofCase.OneofUint32, message2.OneofFieldCase);
+ Assert.AreNotEqual(message1, message2);
+ }
+
+ [Test]
public void OneofSerialization_NonDefaultValue()
{
var message = new TestAllTypes();
@@ -626,7 +670,7 @@ namespace Google.Protobuf
{
// 130, 3 is the message tag
// 1 is the data length - but there's no data.
- var data = new byte[] { 130, 3, 1 };
+ var data = new byte[] { 130, 3, 1 };
Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(data));
}
@@ -635,21 +679,45 @@ namespace Google.Protobuf
/// for details; we may want to change this.
/// </summary>
[Test]
- public void ExtraEndGroupSkipped()
+ public void ExtraEndGroupThrows()
{
var message = SampleMessages.CreateFullTestAllTypes();
var stream = new MemoryStream();
var output = new CodedOutputStream(stream);
- output.WriteTag(100, WireFormat.WireType.EndGroup);
output.WriteTag(TestAllTypes.SingleFixed32FieldNumber, WireFormat.WireType.Fixed32);
output.WriteFixed32(123);
+ output.WriteTag(100, WireFormat.WireType.EndGroup);
output.Flush();
stream.Position = 0;
- var parsed = TestAllTypes.Parser.ParseFrom(stream);
- Assert.AreEqual(new TestAllTypes { SingleFixed32 = 123 }, parsed);
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseFrom(stream));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToStringCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ Assert.AreEqual("{ \"c\": 31, \"@cInHex\": \"1f\" }", message.ToString());
+ Assert.AreEqual("{ \"c\": 31 }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_Nested()
+ {
+ var message = new TestAllTypes { SingleForeignMessage = new ForeignMessage { C = 16 } };
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16, \"@cInHex\": \"10\" } }", message.ToString());
+ Assert.AreEqual("{ \"singleForeignMessage\": { \"c\": 16 } }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void CustomDiagnosticMessage_DirectToTextWriterCall()
+ {
+ var message = new ForeignMessage { C = 31 };
+ var writer = new StringWriter();
+ JsonFormatter.Default.Format(message, writer);
+ Assert.AreEqual("{ \"c\": 31 }", writer.ToString());
}
}
-}
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
index 33be5dae..4f37c5e2 100644
--- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -55,7 +55,7 @@
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<Prefer32Bit>false</Prefer32Bit>
<SignAssembly>True</SignAssembly>
- <AssemblyOriginatorKeyFile>C:\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
+ <AssemblyOriginatorKeyFile>..\..\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="mscorlib" />
@@ -95,10 +95,14 @@
<Compile Include="Collections\MapFieldTest.cs" />
<Compile Include="Collections\RepeatedFieldTest.cs" />
<Compile Include="JsonFormatterTest.cs" />
+ <Compile Include="JsonParserTest.cs" />
+ <Compile Include="JsonTokenizerTest.cs" />
<Compile Include="Reflection\DescriptorsTest.cs" />
<Compile Include="Reflection\FieldAccessTest.cs" />
+ <Compile Include="Reflection\TypeRegistryTest.cs" />
<Compile Include="SampleEnum.cs" />
<Compile Include="SampleMessages.cs" />
+ <Compile Include="TestProtos\ForeignMessagePartial.cs" />
<Compile Include="TestProtos\MapUnittestProto3.cs" />
<Compile Include="TestProtos\UnittestImportProto3.cs" />
<Compile Include="TestProtos\UnittestImportPublicProto3.cs" />
@@ -111,6 +115,7 @@
<Compile Include="TestProtos\UnittestWellKnownTypes.cs" />
<Compile Include="WellKnownTypes\AnyTest.cs" />
<Compile Include="WellKnownTypes\DurationTest.cs" />
+ <Compile Include="WellKnownTypes\FieldMaskTest.cs" />
<Compile Include="WellKnownTypes\TimestampTest.cs" />
<Compile Include="WellKnownTypes\WrappersTest.cs" />
</ItemGroup>
diff --git a/csharp/src/Google.Protobuf.Test/IssuesTest.cs b/csharp/src/Google.Protobuf.Test/IssuesTest.cs
index a0350035..a38d6b08 100644
--- a/csharp/src/Google.Protobuf.Test/IssuesTest.cs
+++ b/csharp/src/Google.Protobuf.Test/IssuesTest.cs
@@ -59,5 +59,24 @@ namespace Google.Protobuf
// Underscores aren't reflected in the JSON.
Assert.AreEqual("{ \"types\": 10, \"descriptor\": 20 }", message.ToString());
}
+
+ [Test]
+ public void JsonNameParseTest()
+ {
+ var settings = new JsonParser.Settings(10, TypeRegistry.FromFiles(UnittestIssuesReflection.Descriptor));
+ var parser = new JsonParser(settings);
+
+ // It is safe to use either original field name or explicitly specified json_name
+ Assert.AreEqual(new TestJsonName { Name = "test", Description = "test2", Guid = "test3" },
+ parser.Parse<TestJsonName>("{ \"name\": \"test\", \"desc\": \"test2\", \"guid\": \"test3\" }"));
+ }
+
+ [Test]
+ public void JsonNameFormatTest()
+ {
+ var message = new TestJsonName { Name = "test", Description = "test2", Guid = "test3" };
+ Assert.AreEqual("{ \"name\": \"test\", \"desc\": \"test2\", \"exid\": \"test3\" }",
+ JsonFormatter.Default.Format(message));
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
index 3e7a3d2e..827a7595 100644
--- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
+++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs
@@ -35,6 +35,9 @@ using Google.Protobuf.TestProtos;
using NUnit.Framework;
using UnitTest.Issues.TestProtos;
using Google.Protobuf.WellKnownTypes;
+using Google.Protobuf.Reflection;
+
+using static Google.Protobuf.JsonParserTest; // For WrapInQuotes
namespace Google.Protobuf
{
@@ -72,13 +75,13 @@ namespace Google.Protobuf
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.IMPORT_BAZ,
+ SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
@@ -162,41 +165,31 @@ namespace Google.Protobuf
}
[Test]
- public void UnknownEnumValueOmitted_SingleField()
+ public void UnknownEnumValueNumeric_SingleField()
{
var message = new TestAllTypes { SingleForeignEnum = (ForeignEnum) 100 };
- AssertJson("{ }", JsonFormatter.Default.Format(message));
+ AssertJson("{ 'singleForeignEnum': 100 }", JsonFormatter.Default.Format(message));
}
[Test]
- public void UnknownEnumValueOmitted_RepeatedField()
+ public void UnknownEnumValueNumeric_RepeatedField()
{
- var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.FOREIGN_BAZ, (ForeignEnum) 100, ForeignEnum.FOREIGN_FOO } };
- AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message));
+ var message = new TestAllTypes { RepeatedForeignEnum = { ForeignEnum.ForeignBaz, (ForeignEnum) 100, ForeignEnum.ForeignFoo } };
+ AssertJson("{ 'repeatedForeignEnum': [ 'FOREIGN_BAZ', 100, 'FOREIGN_FOO' ] }", JsonFormatter.Default.Format(message));
}
[Test]
- public void UnknownEnumValueOmitted_MapField()
+ public void UnknownEnumValueNumeric_MapField()
{
- // This matches the C++ behaviour.
- var message = new TestMap { MapInt32Enum = { { 1, MapEnum.MAP_ENUM_FOO }, { 2, (MapEnum) 100 }, { 3, MapEnum.MAP_ENUM_BAR } } };
- AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message));
+ var message = new TestMap { MapInt32Enum = { { 1, MapEnum.Foo }, { 2, (MapEnum) 100 }, { 3, MapEnum.Bar } } };
+ AssertJson("{ 'mapInt32Enum': { '1': 'MAP_ENUM_FOO', '2': 100, '3': 'MAP_ENUM_BAR' } }", JsonFormatter.Default.Format(message));
}
[Test]
- public void UnknownEnumValueOmitted_RepeatedField_AllEntriesUnknown()
+ public void UnknownEnumValue_RepeatedField_AllEntriesUnknown()
{
- // *Maybe* we should hold off on writing the "[" until we find that we've got at least one value to write...
- // but this is what happens at the moment, and it doesn't seem too awful.
var message = new TestAllTypes { RepeatedForeignEnum = { (ForeignEnum) 200, (ForeignEnum) 100 } };
- AssertJson("{ 'repeatedForeignEnum': [ ] }", JsonFormatter.Default.Format(message));
- }
-
- [Test]
- public void NullValueForMessage()
- {
- var message = new TestMap { MapInt32ForeignMessage = { { 10, null } } };
- AssertJson("{ 'mapInt32ForeignMessage': { '10': null } }", JsonFormatter.Default.Format(message));
+ AssertJson("{ 'repeatedForeignEnum': [ 200, 100 ] }", JsonFormatter.Default.Format(message));
}
[Test]
@@ -276,6 +269,13 @@ namespace Google.Protobuf
}
[Test]
+ public void WrapperFormatting_Message()
+ {
+ Assert.AreEqual("\"\"", JsonFormatter.Default.Format(new StringValue()));
+ Assert.AreEqual("0", JsonFormatter.Default.Format(new Int32Value()));
+ }
+
+ [Test]
public void WrapperFormatting_IncludeNull()
{
// The actual JSON here is very large because there are lots of fields. Just test a couple of them.
@@ -311,27 +311,51 @@ namespace Google.Protobuf
}
[Test]
- public void TimestampStandalone()
+ [TestCase("1970-01-01T00:00:00Z", 0)]
+ [TestCase("1970-01-01T00:00:00.000000001Z", 1)]
+ [TestCase("1970-01-01T00:00:00.000000010Z", 10)]
+ [TestCase("1970-01-01T00:00:00.000000100Z", 100)]
+ [TestCase("1970-01-01T00:00:00.000001Z", 1000)]
+ [TestCase("1970-01-01T00:00:00.000010Z", 10000)]
+ [TestCase("1970-01-01T00:00:00.000100Z", 100000)]
+ [TestCase("1970-01-01T00:00:00.001Z", 1000000)]
+ [TestCase("1970-01-01T00:00:00.010Z", 10000000)]
+ [TestCase("1970-01-01T00:00:00.100Z", 100000000)]
+ [TestCase("1970-01-01T00:00:00.120Z", 120000000)]
+ [TestCase("1970-01-01T00:00:00.123Z", 123000000)]
+ [TestCase("1970-01-01T00:00:00.123400Z", 123400000)]
+ [TestCase("1970-01-01T00:00:00.123450Z", 123450000)]
+ [TestCase("1970-01-01T00:00:00.123456Z", 123456000)]
+ [TestCase("1970-01-01T00:00:00.123456700Z", 123456700)]
+ [TestCase("1970-01-01T00:00:00.123456780Z", 123456780)]
+ [TestCase("1970-01-01T00:00:00.123456789Z", 123456789)]
+ public void TimestampStandalone(string expected, int nanos)
{
- Assert.AreEqual("1970-01-01T00:00:00Z", new Timestamp().ToString());
- Assert.AreEqual("1970-01-01T00:00:00.100Z", new Timestamp { Nanos = 100000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.120Z", new Timestamp { Nanos = 120000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123Z", new Timestamp { Nanos = 123000000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123400Z", new Timestamp { Nanos = 123400000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123450Z", new Timestamp { Nanos = 123450000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456Z", new Timestamp { Nanos = 123456000 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456700Z", new Timestamp { Nanos = 123456700 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456780Z", new Timestamp { Nanos = 123456780 }.ToString());
- Assert.AreEqual("1970-01-01T00:00:00.123456789Z", new Timestamp { Nanos = 123456789 }.ToString());
+ Assert.AreEqual(WrapInQuotes(expected), new Timestamp { Nanos = nanos }.ToString());
+ }
- // One before and one after the Unix epoch
- Assert.AreEqual("1673-06-19T12:34:56Z",
+ [Test]
+ public void TimestampStandalone_FromDateTime()
+ {
+ // One before and one after the Unix epoch, more easily represented via DateTime.
+ Assert.AreEqual("\"1673-06-19T12:34:56Z\"",
new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp().ToString());
- Assert.AreEqual("2015-07-31T10:29:34Z",
+ Assert.AreEqual("\"2015-07-31T10:29:34Z\"",
new DateTime(2015, 7, 31, 10, 29, 34, DateTimeKind.Utc).ToTimestamp().ToString());
}
[Test]
+ [TestCase(-1, -1)] // Would be valid as duration
+ [TestCase(1, Timestamp.MaxNanos + 1)]
+ [TestCase(Timestamp.UnixSecondsAtBclMaxValue + 1, 0)]
+ [TestCase(Timestamp.UnixSecondsAtBclMinValue - 1, 0)]
+ public void TimestampStandalone_NonNormalized(long seconds, int nanoseconds)
+ {
+ var timestamp = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(timestamp));
+ }
+
+ [Test]
public void TimestampField()
{
var message = new TestWellKnownTypes { TimestampField = new Timestamp() };
@@ -342,6 +366,14 @@ namespace Google.Protobuf
[TestCase(0, 0, "0s")]
[TestCase(1, 0, "1s")]
[TestCase(-1, 0, "-1s")]
+ [TestCase(0, 1, "0.000000001s")]
+ [TestCase(0, 10, "0.000000010s")]
+ [TestCase(0, 100, "0.000000100s")]
+ [TestCase(0, 1000, "0.000001s")]
+ [TestCase(0, 10000, "0.000010s")]
+ [TestCase(0, 100000, "0.000100s")]
+ [TestCase(0, 1000000, "0.001s")]
+ [TestCase(0, 10000000, "0.010s")]
[TestCase(0, 100000000, "0.100s")]
[TestCase(0, 120000000, "0.120s")]
[TestCase(0, 123000000, "0.123s")]
@@ -354,12 +386,19 @@ namespace Google.Protobuf
[TestCase(0, -100000000, "-0.100s")]
[TestCase(1, 100000000, "1.100s")]
[TestCase(-1, -100000000, "-1.100s")]
- // Non-normalized examples
- [TestCase(1, 2123456789, "3.123456789s")]
- [TestCase(1, -100000000, "0.900s")]
public void DurationStandalone(long seconds, int nanoseconds, string expected)
{
- Assert.AreEqual(expected, new Duration { Seconds = seconds, Nanos = nanoseconds }.ToString());
+ var json = JsonFormatter.Default.Format(new Duration { Seconds = seconds, Nanos = nanoseconds });
+ Assert.AreEqual(WrapInQuotes(expected), json);
+ }
+
+ [Test]
+ [TestCase(1, 2123456789)]
+ [TestCase(1, -100000000)]
+ public void DurationStandalone_NonNormalized(long seconds, int nanoseconds)
+ {
+ var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(duration));
}
[Test]
@@ -376,26 +415,36 @@ namespace Google.Protobuf
{
Fields =
{
- { "a", new Value { NullValue = new NullValue() } },
- { "b", new Value { BoolValue = false } },
- { "c", new Value { NumberValue = 10.5 } },
- { "d", new Value { StringValue = "text" } },
- { "e", new Value { ListValue = new ListValue { Values = { new Value { StringValue = "t1" }, new Value { NumberValue = 5 } } } } },
- { "f", new Value { StructValue = new Struct { Fields = { { "nested", new Value { StringValue = "value" } } } } } }
+ { "a", Value.ForNull() },
+ { "b", Value.ForBool(false) },
+ { "c", Value.ForNumber(10.5) },
+ { "d", Value.ForString("text") },
+ { "e", Value.ForList(Value.ForString("t1"), Value.ForNumber(5)) },
+ { "f", Value.ForStruct(new Struct { Fields = { { "nested", Value.ForString("value") } } }) }
}
};
AssertJson("{ 'a': null, 'b': false, 'c': 10.5, 'd': 'text', 'e': [ 't1', 5 ], 'f': { 'nested': 'value' } }", message.ToString());
}
[Test]
+ [TestCase("foo__bar")]
+ [TestCase("foo_3_ar")]
+ [TestCase("fooBar")]
+ public void FieldMaskInvalid(string input)
+ {
+ var mask = new FieldMask { Paths = { input } };
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(mask));
+ }
+
+ [Test]
public void FieldMaskStandalone()
{
var fieldMask = new FieldMask { Paths = { "", "single", "with_underscore", "nested.field.name", "nested..double_dot" } };
- Assert.AreEqual(",single,withUnderscore,nested.field.name,nested..doubleDot", fieldMask.ToString());
+ Assert.AreEqual("\",single,withUnderscore,nested.field.name,nested..doubleDot\"", fieldMask.ToString());
// Invalid, but we shouldn't create broken JSON...
fieldMask = new FieldMask { Paths = { "x\\y" } };
- Assert.AreEqual(@"x\\y", fieldMask.ToString());
+ Assert.AreEqual(@"""x\\y""", fieldMask.ToString());
}
[Test]
@@ -405,6 +454,64 @@ namespace Google.Protobuf
AssertJson("{ 'fieldMaskField': 'user.displayName,photo' }", JsonFormatter.Default.Format(message));
}
+ // SourceContext is an example of a well-known type with no special JSON handling
+ [Test]
+ public void SourceContextStandalone()
+ {
+ var message = new SourceContext { FileName = "foo.proto" };
+ AssertJson("{ 'fileName': 'foo.proto' }", JsonFormatter.Default.Format(message));
+ }
+
+ [Test]
+ public void AnyWellKnownType()
+ {
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(Timestamp.Descriptor)));
+ var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
+ var any = Any.Pack(timestamp);
+ AssertJson("{ '@type': 'type.googleapis.com/google.protobuf.Timestamp', 'value': '1673-06-19T12:34:56Z' }", formatter.Format(any));
+ }
+
+ [Test]
+ public void AnyMessageType()
+ {
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
+ var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } };
+ var any = Any.Pack(message);
+ AssertJson("{ '@type': 'type.googleapis.com/protobuf_unittest.TestAllTypes', 'singleInt32': 10, 'singleNestedMessage': { 'bb': 20 } }", formatter.Format(any));
+ }
+
+ [Test]
+ public void AnyMessageType_CustomPrefix()
+ {
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
+ var message = new TestAllTypes { SingleInt32 = 10 };
+ var any = Any.Pack(message, "foo.bar/baz");
+ AssertJson("{ '@type': 'foo.bar/baz/protobuf_unittest.TestAllTypes', 'singleInt32': 10 }", formatter.Format(any));
+ }
+
+ [Test]
+ public void AnyNested()
+ {
+ var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor);
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
+
+ // Nest an Any as the value of an Any.
+ var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 };
+ var nestedMessage = Any.Pack(doubleNestedMessage);
+ var message = new TestWellKnownTypes { AnyField = Any.Pack(nestedMessage) };
+ AssertJson("{ 'anyField': { '@type': 'type.googleapis.com/google.protobuf.Any', 'value': { '@type': 'type.googleapis.com/protobuf_unittest.TestAllTypes', 'singleInt32': 20 } } }",
+ formatter.Format(message));
+ }
+
+ [Test]
+ public void AnyUnknownType()
+ {
+ // The default type registry doesn't have any types in it.
+ var message = new TestAllTypes();
+ var any = Any.Pack(message);
+ Assert.Throws<InvalidOperationException>(() => JsonFormatter.Default.Format(any));
+ }
+
/// <summary>
/// Checks that the actual JSON is the same as the expected JSON - but after replacing
/// all apostrophes in the expected JSON with double quotes. This basically makes the tests easier
diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
new file mode 100644
index 00000000..c3ad851b
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs
@@ -0,0 +1,936 @@
+#region Copyright notice and license
+// 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.
+#endregion
+
+using Google.Protobuf.Reflection;
+using Google.Protobuf.TestProtos;
+using Google.Protobuf.WellKnownTypes;
+using NUnit.Framework;
+using System;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Unit tests for JSON parsing.
+ /// </summary>
+ public class JsonParserTest
+ {
+ // Sanity smoke test
+ [Test]
+ public void AllTypesRoundtrip()
+ {
+ AssertRoundtrip(SampleMessages.CreateFullTestAllTypes());
+ }
+
+ [Test]
+ public void Maps()
+ {
+ AssertRoundtrip(new TestMap { MapStringString = { { "with spaces", "bar" }, { "a", "b" } } });
+ AssertRoundtrip(new TestMap { MapInt32Int32 = { { 0, 1 }, { 2, 3 } } });
+ AssertRoundtrip(new TestMap { MapBoolBool = { { false, true }, { true, false } } });
+ }
+
+ [Test]
+ [TestCase(" 1 ")]
+ [TestCase("+1")]
+ [TestCase("1,000")]
+ [TestCase("1.5")]
+ public void IntegerMapKeysAreStrict(string keyText)
+ {
+ // Test that integer parsing is strict. We assume that if this is correct for int32,
+ // it's correct for other numeric key types.
+ var json = "{ \"mapInt32Int32\": { \"" + keyText + "\" : \"1\" } }";
+ Assert.Throws<InvalidProtocolBufferException>(() => JsonParser.Default.Parse<TestMap>(json));
+ }
+
+ [Test]
+ public void OriginalFieldNameAccepted()
+ {
+ var json = "{ \"single_int32\": 10 }";
+ var expected = new TestAllTypes { SingleInt32 = 10 };
+ Assert.AreEqual(expected, TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void SourceContextRoundtrip()
+ {
+ AssertRoundtrip(new SourceContext { FileName = "foo.proto" });
+ }
+
+ [Test]
+ public void SingularWrappers_DefaultNonNullValues()
+ {
+ var message = new TestWellKnownTypes
+ {
+ StringField = "",
+ BytesField = ByteString.Empty,
+ BoolField = false,
+ FloatField = 0f,
+ DoubleField = 0d,
+ Int32Field = 0,
+ Int64Field = 0,
+ Uint32Field = 0,
+ Uint64Field = 0
+ };
+ AssertRoundtrip(message);
+ }
+
+ [Test]
+ public void SingularWrappers_NonDefaultValues()
+ {
+ var message = new TestWellKnownTypes
+ {
+ StringField = "x",
+ BytesField = ByteString.CopyFrom(1, 2, 3),
+ BoolField = true,
+ FloatField = 12.5f,
+ DoubleField = 12.25d,
+ Int32Field = 1,
+ Int64Field = 2,
+ Uint32Field = 3,
+ Uint64Field = 4
+ };
+ AssertRoundtrip(message);
+ }
+
+ [Test]
+ public void SingularWrappers_ExplicitNulls()
+ {
+ // When we parse the "valueField": null part, we remember it... basically, it's one case
+ // where explicit default values don't fully roundtrip.
+ var message = new TestWellKnownTypes { ValueField = Value.ForNull() };
+ var json = new JsonFormatter(new JsonFormatter.Settings(true)).Format(message);
+ var parsed = JsonParser.Default.Parse<TestWellKnownTypes>(json);
+ Assert.AreEqual(message, parsed);
+ }
+
+ [Test]
+ [TestCase(typeof(Int32Value), "32", 32)]
+ [TestCase(typeof(Int64Value), "32", 32L)]
+ [TestCase(typeof(UInt32Value), "32", 32U)]
+ [TestCase(typeof(UInt64Value), "32", 32UL)]
+ [TestCase(typeof(StringValue), "\"foo\"", "foo")]
+ [TestCase(typeof(FloatValue), "1.5", 1.5f)]
+ [TestCase(typeof(DoubleValue), "1.5", 1.5d)]
+ public void Wrappers_Standalone(System.Type wrapperType, string json, object expectedValue)
+ {
+ IMessage parsed = (IMessage)Activator.CreateInstance(wrapperType);
+ IMessage expected = (IMessage)Activator.CreateInstance(wrapperType);
+ JsonParser.Default.Merge(parsed, "null");
+ Assert.AreEqual(expected, parsed);
+
+ JsonParser.Default.Merge(parsed, json);
+ expected.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.SetValue(expected, expectedValue);
+ Assert.AreEqual(expected, parsed);
+ }
+
+ [Test]
+ public void ExplicitNullValue()
+ {
+ string json = "{\"valueField\": null}";
+ var message = JsonParser.Default.Parse<TestWellKnownTypes>(json);
+ Assert.AreEqual(new TestWellKnownTypes { ValueField = Value.ForNull() }, message);
+ }
+
+ [Test]
+ public void BytesWrapper_Standalone()
+ {
+ ByteString data = ByteString.CopyFrom(1, 2, 3);
+ // Can't do this with attributes...
+ var parsed = JsonParser.Default.Parse<BytesValue>(WrapInQuotes(data.ToBase64()));
+ var expected = new BytesValue { Value = data };
+ Assert.AreEqual(expected, parsed);
+ }
+
+ [Test]
+ public void RepeatedWrappers()
+ {
+ var message = new RepeatedWellKnownTypes
+ {
+ BoolField = { true, false },
+ BytesField = { ByteString.CopyFrom(1, 2, 3), ByteString.CopyFrom(4, 5, 6), ByteString.Empty },
+ DoubleField = { 12.5, -1.5, 0d },
+ FloatField = { 123.25f, -20f, 0f },
+ Int32Field = { int.MaxValue, int.MinValue, 0 },
+ Int64Field = { long.MaxValue, long.MinValue, 0L },
+ StringField = { "First", "Second", "" },
+ Uint32Field = { uint.MaxValue, uint.MinValue, 0U },
+ Uint64Field = { ulong.MaxValue, ulong.MinValue, 0UL },
+ };
+ AssertRoundtrip(message);
+ }
+
+ [Test]
+ public void RepeatedField_NullElementProhibited()
+ {
+ string json = "{ \"repeated_foreign_message\": [null] }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void RepeatedField_NullOverallValueAllowed()
+ {
+ string json = "{ \"repeated_foreign_message\": null }";
+ Assert.AreEqual(new TestAllTypes(), TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("{ \"mapInt32Int32\": { \"10\": null }")]
+ [TestCase("{ \"mapStringString\": { \"abc\": null }")]
+ [TestCase("{ \"mapInt32ForeignMessage\": { \"10\": null }")]
+ public void MapField_NullValueProhibited(string json)
+ {
+ Assert.Throws<InvalidProtocolBufferException>(() => TestMap.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void MapField_NullOverallValueAllowed()
+ {
+ string json = "{ \"mapInt32Int32\": null }";
+ Assert.AreEqual(new TestMap(), TestMap.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void IndividualWrapperTypes()
+ {
+ Assert.AreEqual(new StringValue { Value = "foo" }, StringValue.Parser.ParseJson("\"foo\""));
+ Assert.AreEqual(new Int32Value { Value = 1 }, Int32Value.Parser.ParseJson("1"));
+ // Can parse strings directly too
+ Assert.AreEqual(new Int32Value { Value = 1 }, Int32Value.Parser.ParseJson("\"1\""));
+ }
+
+ private static void AssertRoundtrip<T>(T message) where T : IMessage<T>, new()
+ {
+ var clone = message.Clone();
+ var json = JsonFormatter.Default.Format(message);
+ var parsed = JsonParser.Default.Parse<T>(json);
+ Assert.AreEqual(clone, parsed);
+ }
+
+ [Test]
+ [TestCase("0", 0)]
+ [TestCase("-0", 0)] // Not entirely clear whether we intend to allow this...
+ [TestCase("1", 1)]
+ [TestCase("-1", -1)]
+ [TestCase("2147483647", 2147483647)]
+ [TestCase("-2147483648", -2147483648)]
+ public void StringToInt32_Valid(string jsonValue, int expectedParsedValue)
+ {
+ string json = "{ \"singleInt32\": \"" + jsonValue + "\"}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleInt32);
+ }
+
+ [Test]
+ [TestCase("+0")]
+ [TestCase(" 1")]
+ [TestCase("1 ")]
+ [TestCase("00")]
+ [TestCase("-00")]
+ [TestCase("--1")]
+ [TestCase("+1")]
+ [TestCase("1.5")]
+ [TestCase("1e10")]
+ [TestCase("2147483648")]
+ [TestCase("-2147483649")]
+ public void StringToInt32_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleInt32\": \"" + jsonValue + "\"}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0U)]
+ [TestCase("1", 1U)]
+ [TestCase("4294967295", 4294967295U)]
+ public void StringToUInt32_Valid(string jsonValue, uint expectedParsedValue)
+ {
+ string json = "{ \"singleUint32\": \"" + jsonValue + "\"}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleUint32);
+ }
+
+ // Assume that anything non-bounds-related is covered in the Int32 case
+ [Test]
+ [TestCase("-1")]
+ [TestCase("4294967296")]
+ public void StringToUInt32_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleUint32\": \"" + jsonValue + "\"}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0L)]
+ [TestCase("1", 1L)]
+ [TestCase("-1", -1L)]
+ [TestCase("9223372036854775807", 9223372036854775807)]
+ [TestCase("-9223372036854775808", -9223372036854775808)]
+ public void StringToInt64_Valid(string jsonValue, long expectedParsedValue)
+ {
+ string json = "{ \"singleInt64\": \"" + jsonValue + "\"}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleInt64);
+ }
+
+ // Assume that anything non-bounds-related is covered in the Int32 case
+ [Test]
+ [TestCase("-9223372036854775809")]
+ [TestCase("9223372036854775808")]
+ public void StringToInt64_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleInt64\": \"" + jsonValue + "\"}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0UL)]
+ [TestCase("1", 1UL)]
+ [TestCase("18446744073709551615", 18446744073709551615)]
+ public void StringToUInt64_Valid(string jsonValue, ulong expectedParsedValue)
+ {
+ string json = "{ \"singleUint64\": \"" + jsonValue + "\"}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleUint64);
+ }
+
+ // Assume that anything non-bounds-related is covered in the Int32 case
+ [Test]
+ [TestCase("-1")]
+ [TestCase("18446744073709551616")]
+ public void StringToUInt64_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleUint64\": \"" + jsonValue + "\"}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0d)]
+ [TestCase("1", 1d)]
+ [TestCase("1.000000", 1d)]
+ [TestCase("1.0000000000000000000000001", 1d)] // We don't notice that we haven't preserved the exact value
+ [TestCase("-1", -1d)]
+ [TestCase("1e1", 10d)]
+ [TestCase("1e01", 10d)] // Leading decimals are allowed in exponents
+ [TestCase("1E1", 10d)] // Either case is fine
+ [TestCase("-1e1", -10d)]
+ [TestCase("1.5e1", 15d)]
+ [TestCase("-1.5e1", -15d)]
+ [TestCase("15e-1", 1.5d)]
+ [TestCase("-15e-1", -1.5d)]
+ [TestCase("1.79769e308", 1.79769e308)]
+ [TestCase("-1.79769e308", -1.79769e308)]
+ [TestCase("Infinity", double.PositiveInfinity)]
+ [TestCase("-Infinity", double.NegativeInfinity)]
+ [TestCase("NaN", double.NaN)]
+ public void StringToDouble_Valid(string jsonValue, double expectedParsedValue)
+ {
+ string json = "{ \"singleDouble\": \"" + jsonValue + "\"}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleDouble);
+ }
+
+ [Test]
+ [TestCase("1.7977e308")]
+ [TestCase("-1.7977e308")]
+ [TestCase("1e309")]
+ [TestCase("1,0")]
+ [TestCase("1.0.0")]
+ [TestCase("+1")]
+ [TestCase("00")]
+ [TestCase("01")]
+ [TestCase("-00")]
+ [TestCase("-01")]
+ [TestCase("--1")]
+ [TestCase(" Infinity")]
+ [TestCase(" -Infinity")]
+ [TestCase("NaN ")]
+ [TestCase("Infinity ")]
+ [TestCase("-Infinity ")]
+ [TestCase(" NaN")]
+ [TestCase("INFINITY")]
+ [TestCase("nan")]
+ [TestCase("\u00BD")] // 1/2 as a single Unicode character. Just sanity checking...
+ public void StringToDouble_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleDouble\": \"" + jsonValue + "\"}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0f)]
+ [TestCase("1", 1f)]
+ [TestCase("1.000000", 1f)]
+ [TestCase("-1", -1f)]
+ [TestCase("3.402823e38", 3.402823e38f)]
+ [TestCase("-3.402823e38", -3.402823e38f)]
+ [TestCase("1.5e1", 15f)]
+ [TestCase("15e-1", 1.5f)]
+ public void StringToFloat_Valid(string jsonValue, float expectedParsedValue)
+ {
+ string json = "{ \"singleFloat\": \"" + jsonValue + "\"}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleFloat);
+ }
+
+ [Test]
+ [TestCase("3.402824e38")]
+ [TestCase("-3.402824e38")]
+ [TestCase("1,0")]
+ [TestCase("1.0.0")]
+ [TestCase("+1")]
+ [TestCase("00")]
+ [TestCase("--1")]
+ public void StringToFloat_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleFloat\": \"" + jsonValue + "\"}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0)]
+ [TestCase("-0", 0)] // Not entirely clear whether we intend to allow this...
+ [TestCase("1", 1)]
+ [TestCase("-1", -1)]
+ [TestCase("2147483647", 2147483647)]
+ [TestCase("-2147483648", -2147483648)]
+ [TestCase("1e1", 10)]
+ [TestCase("-1e1", -10)]
+ [TestCase("10.00", 10)]
+ [TestCase("-10.00", -10)]
+ public void NumberToInt32_Valid(string jsonValue, int expectedParsedValue)
+ {
+ string json = "{ \"singleInt32\": " + jsonValue + "}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleInt32);
+ }
+
+ [Test]
+ [TestCase("+0", typeof(InvalidJsonException))]
+ [TestCase("00", typeof(InvalidJsonException))]
+ [TestCase("-00", typeof(InvalidJsonException))]
+ [TestCase("--1", typeof(InvalidJsonException))]
+ [TestCase("+1", typeof(InvalidJsonException))]
+ [TestCase("1.5", typeof(InvalidProtocolBufferException))]
+ // Value is out of range
+ [TestCase("1e10", typeof(InvalidProtocolBufferException))]
+ [TestCase("2147483648", typeof(InvalidProtocolBufferException))]
+ [TestCase("-2147483649", typeof(InvalidProtocolBufferException))]
+ public void NumberToInt32_Invalid(string jsonValue, System.Type expectedExceptionType)
+ {
+ string json = "{ \"singleInt32\": " + jsonValue + "}";
+ Assert.Throws(expectedExceptionType, () => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0U)]
+ [TestCase("1", 1U)]
+ [TestCase("4294967295", 4294967295U)]
+ public void NumberToUInt32_Valid(string jsonValue, uint expectedParsedValue)
+ {
+ string json = "{ \"singleUint32\": " + jsonValue + "}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleUint32);
+ }
+
+ // Assume that anything non-bounds-related is covered in the Int32 case
+ [Test]
+ [TestCase("-1")]
+ [TestCase("4294967296")]
+ public void NumberToUInt32_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleUint32\": " + jsonValue + "}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0L)]
+ [TestCase("1", 1L)]
+ [TestCase("-1", -1L)]
+ // long.MaxValue isn't actually representable as a double. This string value is the highest
+ // representable value which isn't greater than long.MaxValue.
+ [TestCase("9223372036854774784", 9223372036854774784)]
+ [TestCase("-9223372036854775808", -9223372036854775808)]
+ public void NumberToInt64_Valid(string jsonValue, long expectedParsedValue)
+ {
+ string json = "{ \"singleInt64\": " + jsonValue + "}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleInt64);
+ }
+
+ // Assume that anything non-bounds-related is covered in the Int32 case
+ [Test]
+ [TestCase("9223372036854775808")]
+ // Theoretical bound would be -9223372036854775809, but when that is parsed to a double
+ // we end up with the exact value of long.MinValue due to lack of precision. The value here
+ // is the "next double down".
+ [TestCase("-9223372036854780000")]
+ public void NumberToInt64_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleInt64\": " + jsonValue + "}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0UL)]
+ [TestCase("1", 1UL)]
+ // ulong.MaxValue isn't representable as a double. This value is the largest double within
+ // the range of ulong.
+ [TestCase("18446744073709549568", 18446744073709549568UL)]
+ public void NumberToUInt64_Valid(string jsonValue, ulong expectedParsedValue)
+ {
+ string json = "{ \"singleUint64\": " + jsonValue + "}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleUint64);
+ }
+
+ // Assume that anything non-bounds-related is covered in the Int32 case
+ [Test]
+ [TestCase("-1")]
+ [TestCase("18446744073709551616")]
+ public void NumberToUInt64_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleUint64\": " + jsonValue + "}";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0d)]
+ [TestCase("1", 1d)]
+ [TestCase("1.000000", 1d)]
+ [TestCase("1.0000000000000000000000001", 1d)] // We don't notice that we haven't preserved the exact value
+ [TestCase("-1", -1d)]
+ [TestCase("1e1", 10d)]
+ [TestCase("1e01", 10d)] // Leading decimals are allowed in exponents
+ [TestCase("1E1", 10d)] // Either case is fine
+ [TestCase("-1e1", -10d)]
+ [TestCase("1.5e1", 15d)]
+ [TestCase("-1.5e1", -15d)]
+ [TestCase("15e-1", 1.5d)]
+ [TestCase("-15e-1", -1.5d)]
+ [TestCase("1.79769e308", 1.79769e308)]
+ [TestCase("-1.79769e308", -1.79769e308)]
+ public void NumberToDouble_Valid(string jsonValue, double expectedParsedValue)
+ {
+ string json = "{ \"singleDouble\": " + jsonValue + "}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleDouble);
+ }
+
+ [Test]
+ [TestCase("1.7977e308")]
+ [TestCase("-1.7977e308")]
+ [TestCase("1e309")]
+ [TestCase("1,0")]
+ [TestCase("1.0.0")]
+ [TestCase("+1")]
+ [TestCase("00")]
+ [TestCase("--1")]
+ [TestCase("\u00BD")] // 1/2 as a single Unicode character. Just sanity checking...
+ public void NumberToDouble_Invalid(string jsonValue)
+ {
+ string json = "{ \"singleDouble\": " + jsonValue + "}";
+ Assert.Throws<InvalidJsonException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("0", 0f)]
+ [TestCase("1", 1f)]
+ [TestCase("1.000000", 1f)]
+ [TestCase("-1", -1f)]
+ [TestCase("3.402823e38", 3.402823e38f)]
+ [TestCase("-3.402823e38", -3.402823e38f)]
+ [TestCase("1.5e1", 15f)]
+ [TestCase("15e-1", 1.5f)]
+ public void NumberToFloat_Valid(string jsonValue, float expectedParsedValue)
+ {
+ string json = "{ \"singleFloat\": " + jsonValue + "}";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(expectedParsedValue, parsed.SingleFloat);
+ }
+
+ [Test]
+ [TestCase("3.402824e38", typeof(InvalidProtocolBufferException))]
+ [TestCase("-3.402824e38", typeof(InvalidProtocolBufferException))]
+ [TestCase("1,0", typeof(InvalidJsonException))]
+ [TestCase("1.0.0", typeof(InvalidJsonException))]
+ [TestCase("+1", typeof(InvalidJsonException))]
+ [TestCase("00", typeof(InvalidJsonException))]
+ [TestCase("--1", typeof(InvalidJsonException))]
+ public void NumberToFloat_Invalid(string jsonValue, System.Type expectedExceptionType)
+ {
+ string json = "{ \"singleFloat\": " + jsonValue + "}";
+ Assert.Throws(expectedExceptionType, () => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ // The simplest way of testing that the value has parsed correctly is to reformat it,
+ // as we trust the formatting. In many cases that will give the same result as the input,
+ // so in those cases we accept an expectedFormatted value of null. Sometimes the results
+ // will be different though, due to a different number of digits being provided.
+ [Test]
+ // Z offset
+ [TestCase("2015-10-09T14:46:23.123456789Z", null)]
+ [TestCase("2015-10-09T14:46:23.123456Z", null)]
+ [TestCase("2015-10-09T14:46:23.123Z", null)]
+ [TestCase("2015-10-09T14:46:23Z", null)]
+ [TestCase("2015-10-09T14:46:23.123456000Z", "2015-10-09T14:46:23.123456Z")]
+ [TestCase("2015-10-09T14:46:23.1234560Z", "2015-10-09T14:46:23.123456Z")]
+ [TestCase("2015-10-09T14:46:23.123000000Z", "2015-10-09T14:46:23.123Z")]
+ [TestCase("2015-10-09T14:46:23.1230Z", "2015-10-09T14:46:23.123Z")]
+ [TestCase("2015-10-09T14:46:23.00Z", "2015-10-09T14:46:23Z")]
+
+ // +00:00 offset
+ [TestCase("2015-10-09T14:46:23.123456789+00:00", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-09T14:46:23.123456+00:00", "2015-10-09T14:46:23.123456Z")]
+ [TestCase("2015-10-09T14:46:23.123+00:00", "2015-10-09T14:46:23.123Z")]
+ [TestCase("2015-10-09T14:46:23+00:00", "2015-10-09T14:46:23Z")]
+ [TestCase("2015-10-09T14:46:23.123456000+00:00", "2015-10-09T14:46:23.123456Z")]
+ [TestCase("2015-10-09T14:46:23.1234560+00:00", "2015-10-09T14:46:23.123456Z")]
+ [TestCase("2015-10-09T14:46:23.123000000+00:00", "2015-10-09T14:46:23.123Z")]
+ [TestCase("2015-10-09T14:46:23.1230+00:00", "2015-10-09T14:46:23.123Z")]
+ [TestCase("2015-10-09T14:46:23.00+00:00", "2015-10-09T14:46:23Z")]
+
+ // Other offsets (assume by now that the subsecond handling is okay)
+ [TestCase("2015-10-09T15:46:23.123456789+01:00", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-09T13:46:23.123456789-01:00", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-09T15:16:23.123456789+00:30", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-09T14:16:23.123456789-00:30", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-09T16:31:23.123456789+01:45", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-09T13:01:23.123456789-01:45", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-10T08:46:23.123456789+18:00", "2015-10-09T14:46:23.123456789Z")]
+ [TestCase("2015-10-08T20:46:23.123456789-18:00", "2015-10-09T14:46:23.123456789Z")]
+
+ // Leap years and min/max
+ [TestCase("2016-02-29T14:46:23.123456789Z", null)]
+ [TestCase("2000-02-29T14:46:23.123456789Z", null)]
+ [TestCase("0001-01-01T00:00:00Z", null)]
+ [TestCase("9999-12-31T23:59:59.999999999Z", null)]
+ public void Timestamp_Valid(string jsonValue, string expectedFormatted)
+ {
+ expectedFormatted = expectedFormatted ?? jsonValue;
+ string json = WrapInQuotes(jsonValue);
+ var parsed = Timestamp.Parser.ParseJson(json);
+ Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
+ }
+
+ [Test]
+ [TestCase("2015-10-09 14:46:23.123456789Z", Description = "No T between date and time")]
+ [TestCase("2015/10/09T14:46:23.123456789Z", Description = "Wrong date separators")]
+ [TestCase("2015-10-09T14.46.23.123456789Z", Description = "Wrong time separators")]
+ [TestCase("2015-10-09T14:46:23,123456789Z", Description = "Wrong fractional second separators (valid ISO-8601 though)")]
+ [TestCase(" 2015-10-09T14:46:23.123456789Z", Description = "Whitespace at start")]
+ [TestCase("2015-10-09T14:46:23.123456789Z ", Description = "Whitespace at end")]
+ [TestCase("2015-10-09T14:46:23.1234567890", Description = "Too many digits")]
+ [TestCase("2015-10-09T14:46:23.123456789", Description = "No offset")]
+ [TestCase("2015-13-09T14:46:23.123456789Z", Description = "Invalid month")]
+ [TestCase("2015-10-32T14:46:23.123456789Z", Description = "Invalid day")]
+ [TestCase("2015-10-09T24:00:00.000000000Z", Description = "Invalid hour (valid ISO-8601 though)")]
+ [TestCase("2015-10-09T14:60:23.123456789Z", Description = "Invalid minutes")]
+ [TestCase("2015-10-09T14:46:60.123456789Z", Description = "Invalid seconds")]
+ [TestCase("2015-10-09T14:46:23.123456789+18:01", Description = "Offset too large (positive)")]
+ [TestCase("2015-10-09T14:46:23.123456789-18:01", Description = "Offset too large (negative)")]
+ [TestCase("2015-10-09T14:46:23.123456789-00:00", Description = "Local offset (-00:00) makes no sense here")]
+ [TestCase("0001-01-01T00:00:00+00:01", Description = "Value before earliest when offset applied")]
+ [TestCase("9999-12-31T23:59:59.999999999-00:01", Description = "Value after latest when offset applied")]
+ [TestCase("2100-02-29T14:46:23.123456789Z", Description = "Feb 29th on a non-leap-year")]
+ public void Timestamp_Invalid(string jsonValue)
+ {
+ string json = WrapInQuotes(jsonValue);
+ Assert.Throws<InvalidProtocolBufferException>(() => Timestamp.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void StructValue_Null()
+ {
+ Assert.AreEqual(new Value { NullValue = 0 }, Value.Parser.ParseJson("null"));
+ }
+
+ [Test]
+ public void StructValue_String()
+ {
+ Assert.AreEqual(new Value { StringValue = "hi" }, Value.Parser.ParseJson("\"hi\""));
+ }
+
+ [Test]
+ public void StructValue_Bool()
+ {
+ Assert.AreEqual(new Value { BoolValue = true }, Value.Parser.ParseJson("true"));
+ Assert.AreEqual(new Value { BoolValue = false }, Value.Parser.ParseJson("false"));
+ }
+
+ [Test]
+ public void StructValue_List()
+ {
+ Assert.AreEqual(Value.ForList(Value.ForNumber(1), Value.ForString("x")), Value.Parser.ParseJson("[1, \"x\"]"));
+ }
+
+ [Test]
+ public void ParseListValue()
+ {
+ Assert.AreEqual(new ListValue { Values = { Value.ForNumber(1), Value.ForString("x") } }, ListValue.Parser.ParseJson("[1, \"x\"]"));
+ }
+
+ [Test]
+ public void StructValue_Struct()
+ {
+ Assert.AreEqual(
+ Value.ForStruct(new Struct { Fields = { { "x", Value.ForNumber(1) }, { "y", Value.ForString("z") } } }),
+ Value.Parser.ParseJson("{ \"x\": 1, \"y\": \"z\" }"));
+ }
+
+ [Test]
+ public void ParseStruct()
+ {
+ Assert.AreEqual(new Struct { Fields = { { "x", Value.ForNumber(1) }, { "y", Value.ForString("z") } } },
+ Struct.Parser.ParseJson("{ \"x\": 1, \"y\": \"z\" }"));
+ }
+
+ // TODO for duration parsing: upper and lower bounds.
+ // +/- 315576000000 seconds
+
+ [Test]
+ [TestCase("1.123456789s", null)]
+ [TestCase("1.123456s", null)]
+ [TestCase("1.123s", null)]
+ [TestCase("1.12300s", "1.123s")]
+ [TestCase("1.12345s", "1.123450s")]
+ [TestCase("1s", null)]
+ [TestCase("-1.123456789s", null)]
+ [TestCase("-1.123456s", null)]
+ [TestCase("-1.123s", null)]
+ [TestCase("-1s", null)]
+ [TestCase("0.123s", null)]
+ [TestCase("-0.123s", null)]
+ [TestCase("123456.123s", null)]
+ [TestCase("-123456.123s", null)]
+ // Upper and lower bounds
+ [TestCase("315576000000s", null)]
+ [TestCase("-315576000000s", null)]
+ public void Duration_Valid(string jsonValue, string expectedFormatted)
+ {
+ expectedFormatted = expectedFormatted ?? jsonValue;
+ string json = WrapInQuotes(jsonValue);
+ var parsed = Duration.Parser.ParseJson(json);
+ Assert.AreEqual(WrapInQuotes(expectedFormatted), parsed.ToString());
+ }
+
+ // The simplest way of testing that the value has parsed correctly is to reformat it,
+ // as we trust the formatting. In many cases that will give the same result as the input,
+ // so in those cases we accept an expectedFormatted value of null. Sometimes the results
+ // will be different though, due to a different number of digits being provided.
+ [Test]
+ [TestCase("1.1234567890s", Description = "Too many digits")]
+ [TestCase("1.123456789", Description = "No suffix")]
+ [TestCase("1.123456789ss", Description = "Too much suffix")]
+ [TestCase("1.123456789S", Description = "Upper case suffix")]
+ [TestCase("+1.123456789s", Description = "Leading +")]
+ [TestCase(".123456789s", Description = "No integer before the fraction")]
+ [TestCase("1,123456789s", Description = "Comma as decimal separator")]
+ [TestCase("1x1.123456789s", Description = "Non-digit in integer part")]
+ [TestCase("1.1x3456789s", Description = "Non-digit in fractional part")]
+ [TestCase(" 1.123456789s", Description = "Whitespace before fraction")]
+ [TestCase("1.123456789s ", Description = "Whitespace after value")]
+ [TestCase("01.123456789s", Description = "Leading zero (positive)")]
+ [TestCase("-01.123456789s", Description = "Leading zero (negative)")]
+ [TestCase("--0.123456789s", Description = "Double minus sign")]
+ // Violate upper/lower bounds in various ways
+ [TestCase("315576000001s", Description = "Integer part too large")]
+ [TestCase("3155760000000s", Description = "Integer part too long (positive)")]
+ [TestCase("-3155760000000s", Description = "Integer part too long (negative)")]
+ public void Duration_Invalid(string jsonValue)
+ {
+ string json = WrapInQuotes(jsonValue);
+ Assert.Throws<InvalidProtocolBufferException>(() => Duration.Parser.ParseJson(json));
+ }
+
+ // Not as many tests for field masks as I'd like; more to be added when we have more
+ // detailed specifications.
+
+ [Test]
+ [TestCase("")]
+ [TestCase("foo", "foo")]
+ [TestCase("foo,bar", "foo", "bar")]
+ [TestCase("foo.bar", "foo.bar")]
+ [TestCase("fooBar", "foo_bar")]
+ [TestCase("fooBar.bazQux", "foo_bar.baz_qux")]
+ public void FieldMask_Valid(string jsonValue, params string[] expectedPaths)
+ {
+ string json = WrapInQuotes(jsonValue);
+ var parsed = FieldMask.Parser.ParseJson(json);
+ CollectionAssert.AreEqual(expectedPaths, parsed.Paths);
+ }
+
+ [Test]
+ [TestCase("foo_bar")]
+ public void FieldMask_Invalid(string jsonValue)
+ {
+ string json = WrapInQuotes(jsonValue);
+ Assert.Throws<InvalidProtocolBufferException>(() => FieldMask.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void Any_RegularMessage()
+ {
+ var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, TypeRegistry.FromMessages(TestAllTypes.Descriptor)));
+ var message = new TestAllTypes { SingleInt32 = 10, SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 20 } };
+ var original = Any.Pack(message);
+ var json = formatter.Format(original); // This is tested in JsonFormatterTest
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ Assert.AreEqual(original, parser.Parse<Any>(json));
+ string valueFirstJson = "{ \"singleInt32\": 10, \"singleNestedMessage\": { \"bb\": 20 }, \"@type\": \"type.googleapis.com/protobuf_unittest.TestAllTypes\" }";
+ Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
+ }
+
+ [Test]
+ public void Any_CustomPrefix()
+ {
+ var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
+ var message = new TestAllTypes { SingleInt32 = 10 };
+ var original = Any.Pack(message, "custom.prefix/middle-part");
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ string json = "{ \"@type\": \"custom.prefix/middle-part/protobuf_unittest.TestAllTypes\", \"singleInt32\": 10 }";
+ Assert.AreEqual(original, parser.Parse<Any>(json));
+ }
+
+ [Test]
+ public void Any_UnknownType()
+ {
+ string json = "{ \"@type\": \"type.googleapis.com/bogus\" }";
+ Assert.Throws<InvalidOperationException>(() => Any.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void Any_NoTypeUrl()
+ {
+ string json = "{ \"foo\": \"bar\" }";
+ Assert.Throws<InvalidProtocolBufferException>(() => Any.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void Any_WellKnownType()
+ {
+ var registry = TypeRegistry.FromMessages(Timestamp.Descriptor);
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
+ var timestamp = new DateTime(1673, 6, 19, 12, 34, 56, DateTimeKind.Utc).ToTimestamp();
+ var original = Any.Pack(timestamp);
+ var json = formatter.Format(original); // This is tested in JsonFormatterTest
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ Assert.AreEqual(original, parser.Parse<Any>(json));
+ string valueFirstJson = "{ \"value\": \"1673-06-19T12:34:56Z\", \"@type\": \"type.googleapis.com/google.protobuf.Timestamp\" }";
+ Assert.AreEqual(original, parser.Parse<Any>(valueFirstJson));
+ }
+
+ [Test]
+ public void Any_Nested()
+ {
+ var registry = TypeRegistry.FromMessages(TestWellKnownTypes.Descriptor, TestAllTypes.Descriptor);
+ var formatter = new JsonFormatter(new JsonFormatter.Settings(false, registry));
+ var parser = new JsonParser(new JsonParser.Settings(10, registry));
+ var doubleNestedMessage = new TestAllTypes { SingleInt32 = 20 };
+ var nestedMessage = Any.Pack(doubleNestedMessage);
+ var message = new TestWellKnownTypes { AnyField = Any.Pack(nestedMessage) };
+ var json = formatter.Format(message);
+ // Use the descriptor-based parser just for a change.
+ Assert.AreEqual(message, parser.Parse(json, TestWellKnownTypes.Descriptor));
+ }
+
+ [Test]
+ public void DataAfterObject()
+ {
+ string json = "{} 10";
+ Assert.Throws<InvalidJsonException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ /// <summary>
+ /// JSON equivalent to <see cref="CodedInputStreamTest.MaliciousRecursion"/>
+ /// </summary>
+ [Test]
+ public void MaliciousRecursion()
+ {
+ string data64 = CodedInputStreamTest.MakeRecursiveMessage(64).ToString();
+ string data65 = CodedInputStreamTest.MakeRecursiveMessage(65).ToString();
+
+ var parser64 = new JsonParser(new JsonParser.Settings(64));
+ CodedInputStreamTest.AssertMessageDepth(parser64.Parse<TestRecursiveMessage>(data64), 64);
+ Assert.Throws<InvalidProtocolBufferException>(() => parser64.Parse<TestRecursiveMessage>(data65));
+
+ var parser63 = new JsonParser(new JsonParser.Settings(63));
+ Assert.Throws<InvalidProtocolBufferException>(() => parser63.Parse<TestRecursiveMessage>(data64));
+ }
+
+ [Test]
+ [TestCase("AQI")]
+ [TestCase("_-==")]
+ public void Bytes_InvalidBase64(string badBase64)
+ {
+ string json = "{ \"singleBytes\": \"" + badBase64 + "\" }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ [TestCase("\"FOREIGN_BAR\"", ForeignEnum.ForeignBar)]
+ [TestCase("5", ForeignEnum.ForeignBar)]
+ [TestCase("100", (ForeignEnum)100)]
+ public void EnumValid(string value, ForeignEnum expectedValue)
+ {
+ string json = "{ \"singleForeignEnum\": " + value + " }";
+ var parsed = TestAllTypes.Parser.ParseJson(json);
+ Assert.AreEqual(new TestAllTypes { SingleForeignEnum = expectedValue }, parsed);
+ }
+
+ [Test]
+ [TestCase("\"NOT_A_VALID_VALUE\"")]
+ [TestCase("5.5")]
+ public void Enum_Invalid(string value)
+ {
+ string json = "{ \"singleForeignEnum\": " + value + " }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ [Test]
+ public void OneofDuplicate_Invalid()
+ {
+ string json = "{ \"oneofString\": \"x\", \"oneofUint32\": 10 }";
+ Assert.Throws<InvalidProtocolBufferException>(() => TestAllTypes.Parser.ParseJson(json));
+ }
+
+ /// <summary>
+ /// Various tests use strings which have quotes round them for parsing or as the result
+ /// of formatting, but without those quotes being specified in the tests (for the sake of readability).
+ /// This method simply returns the input, wrapped in double quotes.
+ /// </summary>
+ internal static string WrapInQuotes(string text)
+ {
+ return '"' + text + '"';
+ }
+ }
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
new file mode 100644
index 00000000..527ab336
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/JsonTokenizerTest.cs
@@ -0,0 +1,408 @@
+#region Copyright notice and license
+// 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.
+#endregion
+using NUnit.Framework;
+using System;
+using System.IO;
+
+namespace Google.Protobuf
+{
+ public class JsonTokenizerTest
+ {
+ [Test]
+ public void EmptyObjectValue()
+ {
+ AssertTokens("{}", JsonToken.StartObject, JsonToken.EndObject);
+ }
+
+ [Test]
+ public void EmptyArrayValue()
+ {
+ AssertTokens("[]", JsonToken.StartArray, JsonToken.EndArray);
+ }
+
+ [Test]
+ [TestCase("foo", "foo")]
+ [TestCase("tab\\t", "tab\t")]
+ [TestCase("line\\nfeed", "line\nfeed")]
+ [TestCase("carriage\\rreturn", "carriage\rreturn")]
+ [TestCase("back\\bspace", "back\bspace")]
+ [TestCase("form\\ffeed", "form\ffeed")]
+ [TestCase("escaped\\/slash", "escaped/slash")]
+ [TestCase("escaped\\\\backslash", "escaped\\backslash")]
+ [TestCase("escaped\\\"quote", "escaped\"quote")]
+ [TestCase("foo {}[] bar", "foo {}[] bar")]
+ [TestCase("foo\\u09aFbar", "foo\u09afbar")] // Digits, upper hex, lower hex
+ [TestCase("ab\ud800\udc00cd", "ab\ud800\udc00cd")]
+ [TestCase("ab\\ud800\\udc00cd", "ab\ud800\udc00cd")]
+ public void StringValue(string json, string expectedValue)
+ {
+ AssertTokensNoReplacement("\"" + json + "\"", JsonToken.Value(expectedValue));
+ }
+
+ // Valid surrogate pairs, with mixed escaping. These test cases can't be expressed
+ // using TestCase as they have no valid UTF-8 representation.
+ // It's unclear exactly how we should handle a mixture of escaped or not: that can't
+ // come from UTF-8 text, but could come from a .NET string. For the moment,
+ // treat it as valid in the obvious way.
+ [Test]
+ public void MixedSurrogatePairs()
+ {
+ string expected = "\ud800\udc00";
+ AssertTokens("'\\ud800\udc00'", JsonToken.Value(expected));
+ AssertTokens("'\ud800\\udc00'", JsonToken.Value(expected));
+ }
+
+ [Test]
+ public void ObjectDepth()
+ {
+ string json = "{ \"foo\": { \"x\": 1, \"y\": [ 0 ] } }";
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader(json));
+ // If we had more tests like this, I'd introduce a helper method... but for one test, it's not worth it.
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.StartObject, tokenizer.Next());
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Name("foo"), tokenizer.Next());
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.StartObject, tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Name("x"), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Value(1), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.Name("y"), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.StartArray, tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth); // Depth hasn't changed in array
+ Assert.AreEqual(JsonToken.Value(0), tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndArray, tokenizer.Next());
+ Assert.AreEqual(2, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndObject, tokenizer.Next());
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndObject, tokenizer.Next());
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ }
+
+ [Test]
+ public void ObjectDepth_WithPushBack()
+ {
+ string json = "{}";
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader(json));
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ var token = tokenizer.Next();
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ // When we push back a "start object", we should effectively be back to the previous depth.
+ tokenizer.PushBack(token);
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ // Read the same token again, and get back to depth 1
+ token = tokenizer.Next();
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+
+ // Now the same in reverse, with EndObject
+ token = tokenizer.Next();
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ tokenizer.PushBack(token);
+ Assert.AreEqual(1, tokenizer.ObjectDepth);
+ tokenizer.Next();
+ Assert.AreEqual(0, tokenizer.ObjectDepth);
+ }
+
+ [Test]
+ [TestCase("embedded tab\t")]
+ [TestCase("embedded CR\r")]
+ [TestCase("embedded LF\n")]
+ [TestCase("embedded bell\u0007")]
+ [TestCase("bad escape\\a")]
+ [TestCase("incomplete escape\\")]
+ [TestCase("incomplete Unicode escape\\u000")]
+ [TestCase("invalid Unicode escape\\u000H")]
+ // Surrogate pair handling, both in raw .NET strings and escaped. We only need
+ // to detect this in strings, as non-ASCII characters anywhere other than in strings
+ // will already lead to parsing errors.
+ [TestCase("\\ud800")]
+ [TestCase("\\udc00")]
+ [TestCase("\\ud800x")]
+ [TestCase("\\udc00x")]
+ [TestCase("\\udc00\\ud800y")]
+ public void InvalidStringValue(string json)
+ {
+ AssertThrowsAfter("\"" + json + "\"");
+ }
+
+ // Tests for invalid strings that can't be expressed in attributes,
+ // as the constants can't be expressed as UTF-8 strings.
+ [Test]
+ public void InvalidSurrogatePairs()
+ {
+ AssertThrowsAfter("\"\ud800x\"");
+ AssertThrowsAfter("\"\udc00y\"");
+ AssertThrowsAfter("\"\udc00\ud800y\"");
+ }
+
+ [Test]
+ [TestCase("0", 0)]
+ [TestCase("-0", 0)] // We don't distinguish between positive and negative 0
+ [TestCase("1", 1)]
+ [TestCase("-1", -1)]
+ // From here on, assume leading sign is okay...
+ [TestCase("1.125", 1.125)]
+ [TestCase("1.0", 1)]
+ [TestCase("1e5", 100000)]
+ [TestCase("1e000000", 1)] // Weird, but not prohibited by the spec
+ [TestCase("1E5", 100000)]
+ [TestCase("1e+5", 100000)]
+ [TestCase("1E-5", 0.00001)]
+ [TestCase("123E-2", 1.23)]
+ [TestCase("123.45E3", 123450)]
+ [TestCase(" 1 ", 1)]
+ public void NumberValue(string json, double expectedValue)
+ {
+ AssertTokens(json, JsonToken.Value(expectedValue));
+ }
+
+ [Test]
+ [TestCase("00")]
+ [TestCase(".5")]
+ [TestCase("1.")]
+ [TestCase("1e")]
+ [TestCase("1e-")]
+ [TestCase("--")]
+ [TestCase("--1")]
+ [TestCase("-1.7977e308")]
+ [TestCase("1.7977e308")]
+ public void InvalidNumberValue(string json)
+ {
+ AssertThrowsAfter(json);
+ }
+
+ [Test]
+ [TestCase("nul")]
+ [TestCase("nothing")]
+ [TestCase("truth")]
+ [TestCase("fALSEhood")]
+ public void InvalidLiterals(string json)
+ {
+ AssertThrowsAfter(json);
+ }
+
+ [Test]
+ public void NullValue()
+ {
+ AssertTokens("null", JsonToken.Null);
+ }
+
+ [Test]
+ public void TrueValue()
+ {
+ AssertTokens("true", JsonToken.True);
+ }
+
+ [Test]
+ public void FalseValue()
+ {
+ AssertTokens("false", JsonToken.False);
+ }
+
+ [Test]
+ public void SimpleObject()
+ {
+ AssertTokens("{'x': 'y'}",
+ JsonToken.StartObject, JsonToken.Name("x"), JsonToken.Value("y"), JsonToken.EndObject);
+ }
+
+ [Test]
+ [TestCase("[10, 20", 3)]
+ [TestCase("[10,", 2)]
+ [TestCase("[10:20]", 2)]
+ [TestCase("[", 1)]
+ [TestCase("[,", 1)]
+ [TestCase("{", 1)]
+ [TestCase("{,", 1)]
+ [TestCase("{[", 1)]
+ [TestCase("{{", 1)]
+ [TestCase("{0", 1)]
+ [TestCase("{null", 1)]
+ [TestCase("{false", 1)]
+ [TestCase("{true", 1)]
+ [TestCase("}", 0)]
+ [TestCase("]", 0)]
+ [TestCase(",", 0)]
+ [TestCase("'foo' 'bar'", 1)]
+ [TestCase(":", 0)]
+ [TestCase("'foo", 0)] // Incomplete string
+ [TestCase("{ 'foo' }", 2)]
+ [TestCase("{ x:1", 1)] // Property names must be quoted
+ [TestCase("{]", 1)]
+ [TestCase("[}", 1)]
+ [TestCase("[1,", 2)]
+ [TestCase("{'x':0]", 3)]
+ [TestCase("{ 'foo': }", 2)]
+ [TestCase("{ 'foo':'bar', }", 3)]
+ public void InvalidStructure(string json, int expectedValidTokens)
+ {
+ // Note: we don't test that the earlier tokens are exactly as expected,
+ // partly because that's hard to parameterize.
+ var reader = new StringReader(json.Replace('\'', '"'));
+ var tokenizer = JsonTokenizer.FromTextReader(reader);
+ for (int i = 0; i < expectedValidTokens; i++)
+ {
+ Assert.IsNotNull(tokenizer.Next());
+ }
+ Assert.Throws<InvalidJsonException>(() => tokenizer.Next());
+ }
+
+ [Test]
+ public void ArrayMixedType()
+ {
+ AssertTokens("[1, 'foo', null, false, true, [2], {'x':'y' }]",
+ JsonToken.StartArray,
+ JsonToken.Value(1),
+ JsonToken.Value("foo"),
+ JsonToken.Null,
+ JsonToken.False,
+ JsonToken.True,
+ JsonToken.StartArray,
+ JsonToken.Value(2),
+ JsonToken.EndArray,
+ JsonToken.StartObject,
+ JsonToken.Name("x"),
+ JsonToken.Value("y"),
+ JsonToken.EndObject,
+ JsonToken.EndArray);
+ }
+
+ [Test]
+ public void ObjectMixedType()
+ {
+ AssertTokens(@"{'a': 1, 'b': 'bar', 'c': null, 'd': false, 'e': true,
+ 'f': [2], 'g': {'x':'y' }}",
+ JsonToken.StartObject,
+ JsonToken.Name("a"),
+ JsonToken.Value(1),
+ JsonToken.Name("b"),
+ JsonToken.Value("bar"),
+ JsonToken.Name("c"),
+ JsonToken.Null,
+ JsonToken.Name("d"),
+ JsonToken.False,
+ JsonToken.Name("e"),
+ JsonToken.True,
+ JsonToken.Name("f"),
+ JsonToken.StartArray,
+ JsonToken.Value(2),
+ JsonToken.EndArray,
+ JsonToken.Name("g"),
+ JsonToken.StartObject,
+ JsonToken.Name("x"),
+ JsonToken.Value("y"),
+ JsonToken.EndObject,
+ JsonToken.EndObject);
+ }
+
+ [Test]
+ public void NextAfterEndDocumentThrows()
+ {
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader("null"));
+ Assert.AreEqual(JsonToken.Null, tokenizer.Next());
+ Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
+ Assert.Throws<InvalidOperationException>(() => tokenizer.Next());
+ }
+
+ [Test]
+ public void CanPushBackEndDocument()
+ {
+ var tokenizer = JsonTokenizer.FromTextReader(new StringReader("null"));
+ Assert.AreEqual(JsonToken.Null, tokenizer.Next());
+ Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
+ tokenizer.PushBack(JsonToken.EndDocument);
+ Assert.AreEqual(JsonToken.EndDocument, tokenizer.Next());
+ Assert.Throws<InvalidOperationException>(() => tokenizer.Next());
+ }
+
+ /// <summary>
+ /// Asserts that the specified JSON is tokenized into the given sequence of tokens.
+ /// All apostrophes are first converted to double quotes, allowing any tests
+ /// that don't need to check actual apostrophe handling to use apostrophes in the JSON, avoiding
+ /// messy string literal escaping. The "end document" token is not specified in the list of
+ /// expected tokens, but is implicit.
+ /// </summary>
+ private static void AssertTokens(string json, params JsonToken[] expectedTokens)
+ {
+ AssertTokensNoReplacement(json.Replace('\'', '"'), expectedTokens);
+ }
+
+ /// <summary>
+ /// Asserts that the specified JSON is tokenized into the given sequence of tokens.
+ /// Unlike <see cref="AssertTokens(string, JsonToken[])"/>, this does not perform any character
+ /// replacement on the specified JSON, and should be used when the text contains apostrophes which
+ /// are expected to be used *as* apostrophes. The "end document" token is not specified in the list of
+ /// expected tokens, but is implicit.
+ /// </summary>
+ private static void AssertTokensNoReplacement(string json, params JsonToken[] expectedTokens)
+ {
+ var reader = new StringReader(json);
+ var tokenizer = JsonTokenizer.FromTextReader(reader);
+ for (int i = 0; i < expectedTokens.Length; i++)
+ {
+ var actualToken = tokenizer.Next();
+ if (actualToken == JsonToken.EndDocument)
+ {
+ Assert.Fail("Expected {0} but reached end of token stream", expectedTokens[i]);
+ }
+ Assert.AreEqual(expectedTokens[i], actualToken);
+ }
+ var finalToken = tokenizer.Next();
+ if (finalToken != JsonToken.EndDocument)
+ {
+ Assert.Fail("Expected token stream to be exhausted; received {0}", finalToken);
+ }
+ }
+
+ private static void AssertThrowsAfter(string json, params JsonToken[] expectedTokens)
+ {
+ var reader = new StringReader(json);
+ var tokenizer = JsonTokenizer.FromTextReader(reader);
+ for (int i = 0; i < expectedTokens.Length; i++)
+ {
+ var actualToken = tokenizer.Next();
+ if (actualToken == JsonToken.EndDocument)
+ {
+ Assert.Fail("Expected {0} but reached end of document", expectedTokens[i]);
+ }
+ Assert.AreEqual(expectedTokens[i], actualToken);
+ }
+ Assert.Throws<InvalidJsonException>(() => tokenizer.Next());
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
index 5f3aba1a..52d5a676 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/DescriptorsTest.cs
@@ -46,7 +46,7 @@ namespace Google.Protobuf.Reflection
[Test]
public void FileDescriptor()
{
- FileDescriptor file = UnittestProto3.Descriptor;
+ FileDescriptor file = UnittestProto3Reflection.Descriptor;
Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Name);
Assert.AreEqual("protobuf_unittest", file.Package);
@@ -56,14 +56,15 @@ namespace Google.Protobuf.Reflection
// unittest.proto doesn't have any public imports, but unittest_import.proto does.
Assert.AreEqual(0, file.PublicDependencies.Count);
- Assert.AreEqual(1, UnittestImportProto3.Descriptor.PublicDependencies.Count);
- Assert.AreEqual(UnittestImportPublicProto3.Descriptor, UnittestImportProto3.Descriptor.PublicDependencies[0]);
+ Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.PublicDependencies.Count);
+ Assert.AreEqual(UnittestImportPublicProto3Reflection.Descriptor, UnittestImportProto3Reflection.Descriptor.PublicDependencies[0]);
Assert.AreEqual(1, file.Dependencies.Count);
- Assert.AreEqual(UnittestImportProto3.Descriptor, file.Dependencies[0]);
+ Assert.AreEqual(UnittestImportProto3Reflection.Descriptor, file.Dependencies[0]);
MessageDescriptor messageType = TestAllTypes.Descriptor;
- Assert.AreSame(typeof(TestAllTypes), messageType.GeneratedType);
+ Assert.AreSame(typeof(TestAllTypes), messageType.ClrType);
+ Assert.AreSame(TestAllTypes.Parser, messageType.Parser);
Assert.AreEqual(messageType, file.MessageTypes[0]);
Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
Assert.Null(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
@@ -76,8 +77,8 @@ namespace Google.Protobuf.Reflection
Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
Assert.Null(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
Assert.Null(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum"));
- Assert.AreEqual(1, UnittestImportProto3.Descriptor.EnumTypes.Count);
- Assert.AreEqual("ImportEnum", UnittestImportProto3.Descriptor.EnumTypes[0].Name);
+ Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.EnumTypes.Count);
+ Assert.AreEqual("ImportEnum", UnittestImportProto3Reflection.Descriptor.EnumTypes[0].Name);
for (int i = 0; i < file.EnumTypes.Count; i++)
{
Assert.AreEqual(i, file.EnumTypes[i].Index);
@@ -94,7 +95,7 @@ namespace Google.Protobuf.Reflection
Assert.AreEqual("TestAllTypes", messageType.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
- Assert.AreEqual(UnittestProto3.Descriptor, messageType.File);
+ Assert.AreEqual(UnittestProto3Reflection.Descriptor, messageType.File);
Assert.IsNull(messageType.ContainingType);
Assert.IsNull(messageType.Proto.Options);
@@ -102,7 +103,7 @@ namespace Google.Protobuf.Reflection
Assert.AreEqual("NestedMessage", nestedType.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
- Assert.AreEqual(UnittestProto3.Descriptor, nestedType.File);
+ Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Assert.AreEqual(messageType, nestedType.ContainingType);
FieldDescriptor field = messageType.Fields.InDeclarationOrder()[0];
@@ -146,7 +147,7 @@ namespace Google.Protobuf.Reflection
primitiveField.FullName);
Assert.AreEqual(1, primitiveField.FieldNumber);
Assert.AreEqual(messageType, primitiveField.ContainingType);
- Assert.AreEqual(UnittestProto3.Descriptor, primitiveField.File);
+ Assert.AreEqual(UnittestProto3Reflection.Descriptor, primitiveField.File);
Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
Assert.IsNull(primitiveField.Proto.Options);
@@ -175,26 +176,26 @@ namespace Google.Protobuf.Reflection
public void EnumDescriptor()
{
// Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
- EnumDescriptor enumType = UnittestProto3.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
+ EnumDescriptor enumType = UnittestProto3Reflection.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
Assert.AreEqual("ForeignEnum", enumType.Name);
Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName);
- Assert.AreEqual(UnittestProto3.Descriptor, enumType.File);
+ Assert.AreEqual(UnittestProto3Reflection.Descriptor, enumType.File);
Assert.Null(enumType.ContainingType);
Assert.Null(enumType.Proto.Options);
Assert.AreEqual("NestedEnum", nestedType.Name);
Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum",
nestedType.FullName);
- Assert.AreEqual(UnittestProto3.Descriptor, nestedType.File);
+ Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
Assert.AreEqual(value, enumType.Values[1]);
Assert.AreEqual("FOREIGN_FOO", value.Name);
Assert.AreEqual(4, value.Number);
- Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number);
+ Assert.AreEqual((int) ForeignEnum.ForeignFoo, value.Number);
Assert.AreEqual(value, enumType.FindValueByNumber(4));
Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE"));
for (int i = 0; i < enumType.Values.Count; i++)
@@ -226,17 +227,12 @@ namespace Google.Protobuf.Reflection
}
[Test]
- public void ConstructionWithoutGeneratedCodeInfo()
+ public void MapEntryMessageDescriptor()
{
- var data = UnittestIssues.Descriptor.Proto.ToByteArray();
- var newDescriptor = Google.Protobuf.Reflection.FileDescriptor.InternalBuildGeneratedFileFrom(data, new Reflection.FileDescriptor[] { }, null);
-
- // We should still be able to get at a field...
- var messageDescriptor = newDescriptor.FindTypeByName<MessageDescriptor>("ItemField");
- var fieldDescriptor = messageDescriptor.FindFieldByName("item");
- // But there shouldn't be an accessor (or a generated type for the message)
- Assert.IsNull(fieldDescriptor.Accessor);
- Assert.IsNull(messageDescriptor.GeneratedType);
+ var descriptor = MapWellKnownTypes.Descriptor.NestedTypes[0];
+ Assert.IsNull(descriptor.Parser);
+ Assert.IsNull(descriptor.ClrType);
+ Assert.IsNull(descriptor.Fields[1].Accessor);
}
// From TestFieldOrdering:
@@ -257,6 +253,7 @@ namespace Google.Protobuf.Reflection
public void DescriptorProtoFileDescriptor()
{
var descriptor = Google.Protobuf.Reflection.FileDescriptor.DescriptorProtoFileDescriptor;
+ Assert.AreEqual("google/protobuf/descriptor.proto", descriptor.Name);
}
}
}
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
index 936e41c6..a488af30 100644
--- a/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
+++ b/csharp/src/Google.Protobuf.Test/Reflection/FieldAccessTest.cs
@@ -128,7 +128,7 @@ namespace Google.Protobuf.Reflection
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.FOREIGN_FOO);
+ 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);
@@ -138,7 +138,7 @@ namespace Google.Protobuf.Reflection
SingleInt32 = 500,
SingleString = "It's a string",
SingleBytes = ByteString.CopyFrom(99, 98, 97),
- SingleForeignEnum = ForeignEnum.FOREIGN_FOO,
+ SingleForeignEnum = ForeignEnum.ForeignFoo,
SingleForeignMessage = new ForeignMessage { C = 12345 },
SingleDouble = 20150701.5
};
diff --git a/csharp/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs b/csharp/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs
new file mode 100644
index 00000000..5be7ca23
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/Reflection/TypeRegistryTest.cs
@@ -0,0 +1,94 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 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.
+#endregion
+
+using Google.Protobuf.TestProtos;
+using Google.Protobuf.WellKnownTypes;
+using NUnit.Framework;
+
+namespace Google.Protobuf.Reflection
+{
+ public class TypeRegistryTest
+ {
+ // Most of our tests use messages. Simple test that we really can use files...
+ [Test]
+ public void CreateWithFileDescriptor()
+ {
+ var registry = TypeRegistry.FromFiles(DurationReflection.Descriptor, StructReflection.Descriptor);
+ AssertDescriptorPresent(registry, Duration.Descriptor);
+ AssertDescriptorPresent(registry, ListValue.Descriptor);
+ AssertDescriptorAbsent(registry, Timestamp.Descriptor);
+ }
+
+ [Test]
+ public void TypesFromSameFile()
+ {
+ // Just for kicks, let's start with a nested type
+ var registry = TypeRegistry.FromMessages(TestAllTypes.Types.NestedMessage.Descriptor);
+ // Top-level...
+ AssertDescriptorPresent(registry, TestFieldOrderings.Descriptor);
+ // ... and nested (not the same as the original NestedMessage!)
+ AssertDescriptorPresent(registry, TestFieldOrderings.Types.NestedMessage.Descriptor);
+ }
+
+ [Test]
+ public void DependenciesAreIncluded()
+ {
+ var registry = TypeRegistry.FromMessages(TestAllTypes.Descriptor);
+ // Direct dependencies
+ AssertDescriptorPresent(registry, ImportMessage.Descriptor);
+ // Public dependencies
+ AssertDescriptorPresent(registry, PublicImportMessage.Descriptor);
+ }
+
+ [Test]
+ public void DuplicateFiles()
+ {
+ // Duplicates via dependencies and simply via repetition
+ var registry = TypeRegistry.FromFiles(
+ UnittestProto3Reflection.Descriptor, UnittestImportProto3Reflection.Descriptor,
+ TimestampReflection.Descriptor, TimestampReflection.Descriptor);
+ AssertDescriptorPresent(registry, TestAllTypes.Descriptor);
+ AssertDescriptorPresent(registry, ImportMessage.Descriptor);
+ AssertDescriptorPresent(registry, Timestamp.Descriptor);
+ }
+
+ private static void AssertDescriptorPresent(TypeRegistry registry, MessageDescriptor descriptor)
+ {
+ Assert.AreSame(descriptor, registry.Find(descriptor.FullName));
+ }
+
+ private static void AssertDescriptorAbsent(TypeRegistry registry, MessageDescriptor descriptor)
+ {
+ Assert.IsNull(registry.Find(descriptor.FullName));
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Test/SampleMessages.cs b/csharp/src/Google.Protobuf.Test/SampleMessages.cs
index 8a9c7f86..ffa4e2a7 100644
--- a/csharp/src/Google.Protobuf.Test/SampleMessages.cs
+++ b/csharp/src/Google.Protobuf.Test/SampleMessages.cs
@@ -54,13 +54,13 @@ namespace Google.Protobuf
SingleFixed32 = 23,
SingleFixed64 = 1234567890123,
SingleFloat = 12.25f,
- SingleForeignEnum = ForeignEnum.FOREIGN_BAR,
+ SingleForeignEnum = ForeignEnum.ForeignBar,
SingleForeignMessage = new ForeignMessage { C = 10 },
- SingleImportEnum = ImportEnum.IMPORT_BAZ,
+ SingleImportEnum = ImportEnum.ImportBaz,
SingleImportMessage = new ImportMessage { D = 20 },
SingleInt32 = 100,
SingleInt64 = 3210987654321,
- SingleNestedEnum = TestAllTypes.Types.NestedEnum.FOO,
+ SingleNestedEnum = TestAllTypes.Types.NestedEnum.Foo,
SingleNestedMessage = new TestAllTypes.Types.NestedMessage { Bb = 35 },
SinglePublicImportMessage = new PublicImportMessage { E = 54 },
SingleSfixed32 = -123,
@@ -76,13 +76,13 @@ namespace Google.Protobuf
RepeatedFixed32 = { UInt32.MaxValue, 23 },
RepeatedFixed64 = { UInt64.MaxValue, 1234567890123 },
RepeatedFloat = { 100f, 12.25f },
- RepeatedForeignEnum = { ForeignEnum.FOREIGN_FOO, ForeignEnum.FOREIGN_BAR },
+ RepeatedForeignEnum = { ForeignEnum.ForeignFoo, ForeignEnum.ForeignBar },
RepeatedForeignMessage = { new ForeignMessage(), new ForeignMessage { C = 10 } },
- RepeatedImportEnum = { ImportEnum.IMPORT_BAZ, ImportEnum.IMPORT_ENUM_UNSPECIFIED },
+ RepeatedImportEnum = { ImportEnum.ImportBaz, ImportEnum.Unspecified },
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 = { TestAllTypes.Types.NestedEnum.Foo, 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 },
@@ -92,8 +92,8 @@ namespace Google.Protobuf
RepeatedString = { "foo", "bar" },
RepeatedUint32 = { UInt32.MaxValue, UInt32.MinValue },
RepeatedUint64 = { UInt64.MaxValue, UInt32.MinValue },
- OneofString = "Oneof string"
+ OneofString = "Oneof string"
};
}
}
-}
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf.Test/TestCornerCases.cs b/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
index 03fa1855..248f5fa9 100644
--- a/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
+++ b/csharp/src/Google.Protobuf.Test/TestCornerCases.cs
@@ -43,8 +43,8 @@ namespace Google.Protobuf
NegativeEnumMessage msg = new NegativeEnumMessage
{
Value = NegativeEnum.MinusOne,
- Values = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
- PackedValues = { NegativeEnum.NEGATIVE_ENUM_ZERO, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
+ Values = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow },
+ PackedValues = { NegativeEnum.Zero, NegativeEnum.MinusOne, NegativeEnum.FiveBelow }
};
Assert.AreEqual(58, msg.CalculateSize());
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs b/csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs
new file mode 100644
index 00000000..5663a699
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/ForeignMessagePartial.cs
@@ -0,0 +1,45 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+#endregion
+
+namespace Google.Protobuf.TestProtos
+{
+ /// <summary>
+ /// A message with custom diagnostics (to test that they work).
+ /// </summary>
+ public partial class ForeignMessage : ICustomDiagnosticMessage
+ {
+ public string ToDiagnosticString()
+ {
+ return $"{{ \"c\": {C}, \"@cInHex\": \"{C:x}\" }}";
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
index e3991bc8..3ba4a2b6 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/MapUnittestProto3.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/map_unittest_proto3.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class MapUnittestProto3 {
+ public static partial class MapUnittestProto3Reflection {
#region Descriptor
/// <summary>File descriptor for google/protobuf/map_unittest_proto3.proto</summary>
@@ -20,7 +20,7 @@ namespace Google.Protobuf.TestProtos {
}
private static pbr::FileDescriptor descriptor;
- static MapUnittestProto3() {
+ static MapUnittestProto3Reflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Cilnb29nbGUvcHJvdG9idWYvbWFwX3VuaXR0ZXN0X3Byb3RvMy5wcm90bxIR",
@@ -147,16 +147,16 @@ namespace Google.Protobuf.TestProtos {
"dmFsdWUYAiABKAU6AjgBKj8KB01hcEVudW0SEAoMTUFQX0VOVU1fRk9PEAAS",
"EAoMTUFQX0VOVU1fQkFSEAESEAoMTUFQX0VOVU1fQkFaEAJCIPgBAaoCGkdv",
"b2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zYgZwcm90bzM="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.MapEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMap), new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapInt32Bytes", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMapSubmessage), new[]{ "TestMap" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMessageMap), new[]{ "MapInt32Message" }, null, null, new pbr::GeneratedCodeInfo[] { null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestSameTypeMap), new[]{ "Map1", "Map2" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestArenaMap), new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType), new[]{ "Type" }, null, new[]{ typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Types.Type) }, new pbr::GeneratedCodeInfo[] { null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry), new[]{ "Entry" }, null, null, new pbr::GeneratedCodeInfo[] { null, })
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.MapEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMap), global::Google.Protobuf.TestProtos.TestMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapStringString", "MapInt32Bytes", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMapSubmessage), global::Google.Protobuf.TestProtos.TestMapSubmessage.Parser, new[]{ "TestMap" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMessageMap), global::Google.Protobuf.TestProtos.TestMessageMap.Parser, new[]{ "MapInt32Message" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestSameTypeMap), global::Google.Protobuf.TestProtos.TestSameTypeMap.Parser, new[]{ "Map1", "Map2" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestArenaMap), global::Google.Protobuf.TestProtos.TestArenaMap.Parser, new[]{ "MapInt32Int32", "MapInt64Int64", "MapUint32Uint32", "MapUint64Uint64", "MapSint32Sint32", "MapSint64Sint64", "MapFixed32Fixed32", "MapFixed64Fixed64", "MapSfixed32Sfixed32", "MapSfixed64Sfixed64", "MapInt32Float", "MapInt32Double", "MapBoolBool", "MapInt32Enum", "MapInt32ForeignMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType), global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Parser, new[]{ "Type" }, null, new[]{ typeof(global::Google.Protobuf.TestProtos.MessageContainingEnumCalledType.Types.Type) }, new pbr::GeneratedClrTypeInfo[] { null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry), global::Google.Protobuf.TestProtos.MessageContainingMapCalledEntry.Parser, new[]{ "Entry" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, })
}));
}
#endregion
@@ -164,9 +164,9 @@ namespace Google.Protobuf.TestProtos {
}
#region Enums
public enum MapEnum {
- MAP_ENUM_FOO = 0,
- MAP_ENUM_BAR = 1,
- MAP_ENUM_BAZ = 2,
+ [pbr::OriginalName("MAP_ENUM_FOO")] Foo = 0,
+ [pbr::OriginalName("MAP_ENUM_BAR")] Bar = 1,
+ [pbr::OriginalName("MAP_ENUM_BAZ")] Baz = 2,
}
#endregion
@@ -181,7 +181,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestMap> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.MapUnittestProto3.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -425,7 +425,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -580,7 +580,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestMapSubmessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.MapUnittestProto3.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -633,7 +633,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -689,7 +689,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestMessageMap> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.MapUnittestProto3.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -741,7 +741,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -787,7 +787,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestSameTypeMap> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.MapUnittestProto3.Descriptor.MessageTypes[3]; }
+ get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -851,7 +851,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -901,7 +901,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestArenaMap> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.MapUnittestProto3.Descriptor.MessageTypes[4]; }
+ get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[4]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1121,7 +1121,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1266,7 +1266,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<MessageContainingEnumCalledType> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.MapUnittestProto3.Descriptor.MessageTypes[5]; }
+ get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[5]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1318,7 +1318,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1358,7 +1358,7 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class Types {
public enum Type {
- TYPE_FOO = 0,
+ [pbr::OriginalName("TYPE_FOO")] Foo = 0,
}
}
@@ -1375,7 +1375,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<MessageContainingMapCalledEntry> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.MapUnittestProto3.Descriptor.MessageTypes[6]; }
+ get { return global::Google.Protobuf.TestProtos.MapUnittestProto3Reflection.Descriptor.MessageTypes[6]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1427,7 +1427,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
index a55c66e0..263e17c0 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportProto3.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_import_proto3.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class UnittestImportProto3 {
+ public static partial class UnittestImportProto3Reflection {
#region Descriptor
/// <summary>File descriptor for google/protobuf/unittest_import_proto3.proto</summary>
@@ -20,7 +20,7 @@ namespace Google.Protobuf.TestProtos {
}
private static pbr::FileDescriptor descriptor;
- static UnittestImportProto3() {
+ static UnittestImportProto3Reflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Cixnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3Byb3RvMy5wcm90",
@@ -31,10 +31,10 @@ namespace Google.Protobuf.TestProtos {
"UhAIEg4KCklNUE9SVF9CQVoQCUI8Chhjb20uZ29vZ2xlLnByb3RvYnVmLnRl",
"c3RIAfgBAaoCGkdvb2dsZS5Qcm90b2J1Zi5UZXN0UHJvdG9zUABiBnByb3Rv",
"Mw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportPublicProto3.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), new[]{ "D" }, null, null, null)
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportPublicProto3Reflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ImportEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.ImportMessage), global::Google.Protobuf.TestProtos.ImportMessage.Parser, new[]{ "D" }, null, null, null)
}));
}
#endregion
@@ -42,10 +42,10 @@ namespace Google.Protobuf.TestProtos {
}
#region Enums
public enum ImportEnum {
- IMPORT_ENUM_UNSPECIFIED = 0,
- IMPORT_FOO = 7,
- IMPORT_BAR = 8,
- IMPORT_BAZ = 9,
+ [pbr::OriginalName("IMPORT_ENUM_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("IMPORT_FOO")] ImportFoo = 7,
+ [pbr::OriginalName("IMPORT_BAR")] ImportBar = 8,
+ [pbr::OriginalName("IMPORT_BAZ")] ImportBaz = 9,
}
#endregion
@@ -57,7 +57,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<ImportMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestImportProto3.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestImportProto3Reflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -110,7 +110,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
index 81696d70..b471a8cf 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestImportPublicProto3.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_import_public_proto3.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class UnittestImportPublicProto3 {
+ public static partial class UnittestImportPublicProto3Reflection {
#region Descriptor
/// <summary>File descriptor for google/protobuf/unittest_import_public_proto3.proto</summary>
@@ -20,17 +20,17 @@ namespace Google.Protobuf.TestProtos {
}
private static pbr::FileDescriptor descriptor;
- static UnittestImportPublicProto3() {
+ static UnittestImportPublicProto3Reflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CjNnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0X3B1YmxpY19wcm90",
"bzMucHJvdG8SGHByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydCIgChNQdWJsaWNJ",
"bXBvcnRNZXNzYWdlEgkKAWUYASABKAVCNwoYY29tLmdvb2dsZS5wcm90b2J1",
"Zi50ZXN0qgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), new[]{ "E" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.PublicImportMessage), global::Google.Protobuf.TestProtos.PublicImportMessage.Parser, new[]{ "E" }, null, null, null)
}));
}
#endregion
@@ -43,7 +43,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<PublicImportMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestImportPublicProto3.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestImportPublicProto3Reflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -96,7 +96,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
index addec057..7d4451b0 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestIssues.cs
@@ -11,7 +11,7 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Holder for reflection information generated from unittest_issues.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class UnittestIssues {
+ public static partial class UnittestIssuesReflection {
#region Descriptor
/// <summary>File descriptor for unittest_issues.proto</summary>
@@ -20,7 +20,7 @@ namespace UnitTest.Issues.TestProtos {
}
private static pbr::FileDescriptor descriptor;
- static UnittestIssues() {
+ static UnittestIssuesReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChV1bml0dGVzdF9pc3N1ZXMucHJvdG8SD3VuaXR0ZXN0X2lzc3VlcyInCghJ",
@@ -42,20 +42,23 @@ namespace UnitTest.Issues.TestProtos {
"CgtwbGFpbl9pbnQzMhgEIAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghv",
"MV9pbnQzMhgFIAEoBUgAEhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9p",
"bnQzMhgGIAEoBUgBEhMKCW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8y",
- "KlUKDE5lZ2F0aXZlRW51bRIWChJORUdBVElWRV9FTlVNX1pFUk8QABIWCglG",
- "aXZlQmVsb3cQ+///////////ARIVCghNaW51c09uZRD///////////8BKi4K",
- "DkRlcHJlY2F0ZWRFbnVtEhMKD0RFUFJFQ0FURURfWkVSTxAAEgcKA29uZRAB",
- "Qh9IAaoCGlVuaXRUZXN0Lklzc3Vlcy5UZXN0UHJvdG9zYgZwcm90bzM="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+ "IksKDFRlc3RKc29uTmFtZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9u",
+ "GAIgASgJUgRkZXNjEhIKBGd1aWQYAyABKAlSBGV4aWQqVQoMTmVnYXRpdmVF",
+ "bnVtEhYKEk5FR0FUSVZFX0VOVU1fWkVSTxAAEhYKCUZpdmVCZWxvdxD7////",
+ "//////8BEhUKCE1pbnVzT25lEP///////////wEqLgoORGVwcmVjYXRlZEVu",
+ "dW0SEwoPREVQUkVDQVRFRF9aRVJPEAASBwoDb25lEAFCH0gBqgIaVW5pdFRl",
+ "c3QuSXNzdWVzLlRlc3RQcm90b3NiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), null, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), null, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), null, null, null, null)})}),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), new[]{ "Value", "Values", "PackedValues" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedChild), null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), new[]{ "Item" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), null, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null)
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null)})}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedChild), global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null)
}));
}
#endregion
@@ -63,14 +66,14 @@ namespace UnitTest.Issues.TestProtos {
}
#region Enums
public enum NegativeEnum {
- NEGATIVE_ENUM_ZERO = 0,
- FiveBelow = -5,
- MinusOne = -1,
+ [pbr::OriginalName("NEGATIVE_ENUM_ZERO")] Zero = 0,
+ [pbr::OriginalName("FiveBelow")] FiveBelow = -5,
+ [pbr::OriginalName("MinusOne")] MinusOne = -1,
}
public enum DeprecatedEnum {
- DEPRECATED_ZERO = 0,
- one = 1,
+ [pbr::OriginalName("DEPRECATED_ZERO")] DeprecatedZero = 0,
+ [pbr::OriginalName("one")] One = 1,
}
#endregion
@@ -86,7 +89,7 @@ namespace UnitTest.Issues.TestProtos {
public static pb::MessageParser<Issue307> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::UnitTest.Issues.TestProtos.UnittestIssues.Descriptor.MessageTypes[0]; }
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -126,7 +129,7 @@ namespace UnitTest.Issues.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -204,7 +207,7 @@ namespace UnitTest.Issues.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -282,7 +285,7 @@ namespace UnitTest.Issues.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -328,7 +331,7 @@ namespace UnitTest.Issues.TestProtos {
public static pb::MessageParser<NegativeEnumMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::UnitTest.Issues.TestProtos.UnittestIssues.Descriptor.MessageTypes[1]; }
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -353,7 +356,7 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "value" field.</summary>
public const int ValueFieldNumber = 1;
- private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO;
+ private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = 0;
public global::UnitTest.Issues.TestProtos.NegativeEnum Value {
get { return value_; }
set {
@@ -398,18 +401,18 @@ namespace UnitTest.Issues.TestProtos {
public override int GetHashCode() {
int hash = 1;
- if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) hash ^= Value.GetHashCode();
+ if (Value != 0) hash ^= Value.GetHashCode();
hash ^= values_.GetHashCode();
hash ^= packedValues_.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
- if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
+ if (Value != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) Value);
}
@@ -419,7 +422,7 @@ namespace UnitTest.Issues.TestProtos {
public int CalculateSize() {
int size = 0;
- if (Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
+ if (Value != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Value);
}
size += values_.CalculateSize(_repeated_values_codec);
@@ -431,7 +434,7 @@ namespace UnitTest.Issues.TestProtos {
if (other == null) {
return;
}
- if (other.Value != global::UnitTest.Issues.TestProtos.NegativeEnum.NEGATIVE_ENUM_ZERO) {
+ if (other.Value != 0) {
Value = other.Value;
}
values_.Add(other.values_);
@@ -471,7 +474,7 @@ namespace UnitTest.Issues.TestProtos {
public static pb::MessageParser<DeprecatedChild> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::UnitTest.Issues.TestProtos.UnittestIssues.Descriptor.MessageTypes[2]; }
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -511,7 +514,7 @@ namespace UnitTest.Issues.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -547,7 +550,7 @@ namespace UnitTest.Issues.TestProtos {
public static pb::MessageParser<DeprecatedFieldsMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::UnitTest.Issues.TestProtos.UnittestIssues.Descriptor.MessageTypes[3]; }
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -617,7 +620,7 @@ namespace UnitTest.Issues.TestProtos {
/// <summary>Field number for the "EnumValue" field.</summary>
public const int EnumValueFieldNumber = 5;
- private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO;
+ private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = 0;
[global::System.ObsoleteAttribute()]
public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue {
get { return enumValue_; }
@@ -662,13 +665,13 @@ namespace UnitTest.Issues.TestProtos {
hash ^= primitiveArray_.GetHashCode();
if (messageValue_ != null) hash ^= MessageValue.GetHashCode();
hash ^= messageArray_.GetHashCode();
- if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) hash ^= EnumValue.GetHashCode();
+ if (EnumValue != 0) hash ^= EnumValue.GetHashCode();
hash ^= enumArray_.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -682,7 +685,7 @@ namespace UnitTest.Issues.TestProtos {
output.WriteMessage(MessageValue);
}
messageArray_.WriteTo(output, _repeated_messageArray_codec);
- if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
+ if (EnumValue != 0) {
output.WriteRawTag(40);
output.WriteEnum((int) EnumValue);
}
@@ -699,7 +702,7 @@ namespace UnitTest.Issues.TestProtos {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageValue);
}
size += messageArray_.CalculateSize(_repeated_messageArray_codec);
- if (EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
+ if (EnumValue != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumValue);
}
size += enumArray_.CalculateSize(_repeated_enumArray_codec);
@@ -721,7 +724,7 @@ namespace UnitTest.Issues.TestProtos {
MessageValue.MergeFrom(other.MessageValue);
}
messageArray_.Add(other.messageArray_);
- if (other.EnumValue != global::UnitTest.Issues.TestProtos.DeprecatedEnum.DEPRECATED_ZERO) {
+ if (other.EnumValue != 0) {
EnumValue = other.EnumValue;
}
enumArray_.Add(other.enumArray_);
@@ -778,7 +781,7 @@ namespace UnitTest.Issues.TestProtos {
public static pb::MessageParser<ItemField> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::UnitTest.Issues.TestProtos.UnittestIssues.Descriptor.MessageTypes[4]; }
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[4]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -831,7 +834,7 @@ namespace UnitTest.Issues.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -881,7 +884,7 @@ namespace UnitTest.Issues.TestProtos {
public static pb::MessageParser<ReservedNames> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::UnitTest.Issues.TestProtos.UnittestIssues.Descriptor.MessageTypes[5]; }
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[5]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -947,7 +950,7 @@ namespace UnitTest.Issues.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1056,7 +1059,7 @@ namespace UnitTest.Issues.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1109,7 +1112,7 @@ namespace UnitTest.Issues.TestProtos {
public static pb::MessageParser<TestJsonFieldOrdering> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::UnitTest.Issues.TestProtos.UnittestIssues.Descriptor.MessageTypes[6]; }
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[6]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1164,7 +1167,7 @@ namespace UnitTest.Issues.TestProtos {
public string O1String {
get { return o1Case_ == O1OneofCase.O1String ? (string) o1_ : ""; }
set {
- o1_ = pb::Preconditions.CheckNotNull(value, "value");
+ o1_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
o1Case_ = O1OneofCase.O1String;
}
}
@@ -1185,7 +1188,7 @@ namespace UnitTest.Issues.TestProtos {
public string PlainString {
get { return plainString_; }
set {
- plainString_ = pb::Preconditions.CheckNotNull(value, "value");
+ plainString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1204,7 +1207,7 @@ namespace UnitTest.Issues.TestProtos {
public string O2String {
get { return o2Case_ == O2OneofCase.O2String ? (string) o2_ : ""; }
set {
- o2_ = pb::Preconditions.CheckNotNull(value, "value");
+ o2_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
o2Case_ = O2OneofCase.O2String;
}
}
@@ -1260,6 +1263,8 @@ namespace UnitTest.Issues.TestProtos {
if (PlainString != other.PlainString) return false;
if (O2Int32 != other.O2Int32) return false;
if (O2String != other.O2String) return false;
+ if (O1Case != other.O1Case) return false;
+ if (O2Case != other.O2Case) return false;
return true;
}
@@ -1271,11 +1276,13 @@ namespace UnitTest.Issues.TestProtos {
if (PlainString.Length != 0) hash ^= PlainString.GetHashCode();
if (o2Case_ == O2OneofCase.O2Int32) hash ^= O2Int32.GetHashCode();
if (o2Case_ == O2OneofCase.O2String) hash ^= O2String.GetHashCode();
+ hash ^= (int) o1Case_;
+ hash ^= (int) o2Case_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1395,6 +1402,166 @@ namespace UnitTest.Issues.TestProtos {
}
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public sealed partial class TestJsonName : pb::IMessage<TestJsonName> {
+ private static readonly pb::MessageParser<TestJsonName> _parser = new pb::MessageParser<TestJsonName>(() => new TestJsonName());
+ public static pb::MessageParser<TestJsonName> Parser { get { return _parser; } }
+
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[7]; }
+ }
+
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ public TestJsonName() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ public TestJsonName(TestJsonName other) : this() {
+ name_ = other.name_;
+ description_ = other.description_;
+ guid_ = other.guid_;
+ }
+
+ public TestJsonName Clone() {
+ return new TestJsonName(this);
+ }
+
+ /// <summary>Field number for the "name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ /// <summary>
+ /// Message for testing the effects for of the json_name option
+ /// </summary>
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "description" field.</summary>
+ public const int DescriptionFieldNumber = 2;
+ private string description_ = "";
+ public string Description {
+ get { return description_; }
+ set {
+ description_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "guid" field.</summary>
+ public const int GuidFieldNumber = 3;
+ private string guid_ = "";
+ public string Guid {
+ get { return guid_; }
+ set {
+ guid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ public override bool Equals(object other) {
+ return Equals(other as TestJsonName);
+ }
+
+ public bool Equals(TestJsonName other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ if (Description != other.Description) return false;
+ if (Guid != other.Guid) return false;
+ return true;
+ }
+
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ if (Description.Length != 0) hash ^= Description.GetHashCode();
+ if (Guid.Length != 0) hash ^= Guid.GetHashCode();
+ return hash;
+ }
+
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ if (Description.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(Description);
+ }
+ if (Guid.Length != 0) {
+ output.WriteRawTag(26);
+ output.WriteString(Guid);
+ }
+ }
+
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ if (Description.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Description);
+ }
+ if (Guid.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Guid);
+ }
+ return size;
+ }
+
+ public void MergeFrom(TestJsonName other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ if (other.Description.Length != 0) {
+ Description = other.Description;
+ }
+ if (other.Guid.Length != 0) {
+ Guid = other.Guid;
+ }
+ }
+
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ case 18: {
+ Description = input.ReadString();
+ break;
+ }
+ case 26: {
+ Guid = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
#endregion
}
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
index 0c7b5279..b8d159bb 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestProto3.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_proto3.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class UnittestProto3 {
+ public static partial class UnittestProto3Reflection {
#region Descriptor
/// <summary>File descriptor for google/protobuf/unittest_proto3.proto</summary>
@@ -20,7 +20,7 @@ namespace Google.Protobuf.TestProtos {
}
private static pbr::FileDescriptor descriptor;
- static UnittestProto3() {
+ static UnittestProto3Reflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CiVnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zLnByb3RvEhFwcm90",
@@ -150,42 +150,42 @@ namespace Google.Protobuf.TestProtos {
"HS5wcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1ZXN0Gh4ucHJvdG9idWZfdW5p",
"dHRlc3QuQmFyUmVzcG9uc2VCOkINVW5pdHRlc3RQcm90b0gBgAEBiAEBkAEB",
"+AEBqgIaR29vZ2xlLlByb3RvYnVmLlRlc3RQcm90b3NiBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportProto3.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ForeignEnum), typeof(global::Google.Protobuf.TestProtos.TestEnumWithDupValue), typeof(global::Google.Protobuf.TestProtos.TestSparseEnum), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes), new[]{ "SingleInt32", "SingleInt64", "SingleUint32", "SingleUint64", "SingleSint32", "SingleSint64", "SingleFixed32", "SingleFixed64", "SingleSfixed32", "SingleSfixed64", "SingleFloat", "SingleDouble", "SingleBool", "SingleString", "SingleBytes", "SingleNestedMessage", "SingleForeignMessage", "SingleImportMessage", "SingleNestedEnum", "SingleForeignEnum", "SingleImportEnum", "SinglePublicImportMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedPublicImportMessage", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage), new[]{ "Bb" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.NestedTestAllTypes), new[]{ "Child", "Payload", "RepeatedChild" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestDeprecatedFields), new[]{ "DeprecatedInt32" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.ForeignMessage), new[]{ "C" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestReservedFields), null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestForeignNested), new[]{ "ForeignNested" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber), new[]{ "A", "Bb" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestRecursiveMessage), new[]{ "A", "I" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionA), new[]{ "Bb" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionB), new[]{ "A", "OptionalInt32" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames), new[]{ "PrimitiveField", "StringField", "EnumField", "MessageField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedEnumField", "RepeatedMessageField" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings), new[]{ "MyString", "MyInt", "MyFloat", "SingleNestedMessage" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage), new[]{ "Oo", "Bb" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.SparseEnumMessage), new[]{ "SparseEnum" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneString), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MoreString), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneBytes), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MoreBytes), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Int32Message), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Uint32Message), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Int64Message), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.Uint64Message), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BoolMessage), new[]{ "Data" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestOneof), new[]{ "FooInt", "FooString", "FooMessage" }, new[]{ "Foo" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestPackedTypes), new[]{ "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedEnum" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestUnpackedTypes), new[]{ "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedEnum" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes), new[]{ "RepeatedFixed32", "RepeatedInt32", "RepeatedFixed64", "RepeatedInt64", "RepeatedFloat", "RepeatedUint64" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestCommentInjectionMessage), new[]{ "A" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooRequest), null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooResponse), null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooClientMessage), null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.FooServerMessage), null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BarRequest), null, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.BarResponse), null, null, null, null)
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Google.Protobuf.TestProtos.UnittestImportProto3Reflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.TestProtos.ForeignEnum), typeof(global::Google.Protobuf.TestProtos.TestEnumWithDupValue), typeof(global::Google.Protobuf.TestProtos.TestSparseEnum), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes), global::Google.Protobuf.TestProtos.TestAllTypes.Parser, new[]{ "SingleInt32", "SingleInt64", "SingleUint32", "SingleUint64", "SingleSint32", "SingleSint64", "SingleFixed32", "SingleFixed64", "SingleSfixed32", "SingleSfixed64", "SingleFloat", "SingleDouble", "SingleBool", "SingleString", "SingleBytes", "SingleNestedMessage", "SingleForeignMessage", "SingleImportMessage", "SingleNestedEnum", "SingleForeignEnum", "SingleImportEnum", "SinglePublicImportMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedPublicImportMessage", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes" }, new[]{ "OneofField" }, new[]{ typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedMessage.Parser, new[]{ "Bb" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.NestedTestAllTypes), global::Google.Protobuf.TestProtos.NestedTestAllTypes.Parser, new[]{ "Child", "Payload", "RepeatedChild" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestDeprecatedFields), global::Google.Protobuf.TestProtos.TestDeprecatedFields.Parser, new[]{ "DeprecatedInt32" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.ForeignMessage), global::Google.Protobuf.TestProtos.ForeignMessage.Parser, new[]{ "C" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestReservedFields), global::Google.Protobuf.TestProtos.TestReservedFields.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestForeignNested), global::Google.Protobuf.TestProtos.TestForeignNested.Parser, new[]{ "ForeignNested" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber), global::Google.Protobuf.TestProtos.TestReallyLargeTagNumber.Parser, new[]{ "A", "Bb" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestRecursiveMessage), global::Google.Protobuf.TestProtos.TestRecursiveMessage.Parser, new[]{ "A", "I" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionA), global::Google.Protobuf.TestProtos.TestMutualRecursionA.Parser, new[]{ "Bb" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestMutualRecursionB), global::Google.Protobuf.TestProtos.TestMutualRecursionB.Parser, new[]{ "A", "OptionalInt32" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames), global::Google.Protobuf.TestProtos.TestCamelCaseFieldNames.Parser, new[]{ "PrimitiveField", "StringField", "EnumField", "MessageField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedEnumField", "RepeatedMessageField" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings), global::Google.Protobuf.TestProtos.TestFieldOrderings.Parser, new[]{ "MyString", "MyInt", "MyFloat", "SingleNestedMessage" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage), global::Google.Protobuf.TestProtos.TestFieldOrderings.Types.NestedMessage.Parser, new[]{ "Oo", "Bb" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.SparseEnumMessage), global::Google.Protobuf.TestProtos.SparseEnumMessage.Parser, new[]{ "SparseEnum" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneString), global::Google.Protobuf.TestProtos.OneString.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MoreString), global::Google.Protobuf.TestProtos.MoreString.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneBytes), global::Google.Protobuf.TestProtos.OneBytes.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MoreBytes), global::Google.Protobuf.TestProtos.MoreBytes.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Int32Message), global::Google.Protobuf.TestProtos.Int32Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Uint32Message), global::Google.Protobuf.TestProtos.Uint32Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Int64Message), global::Google.Protobuf.TestProtos.Int64Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.Uint64Message), global::Google.Protobuf.TestProtos.Uint64Message.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.BoolMessage), global::Google.Protobuf.TestProtos.BoolMessage.Parser, new[]{ "Data" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestOneof), global::Google.Protobuf.TestProtos.TestOneof.Parser, new[]{ "FooInt", "FooString", "FooMessage" }, new[]{ "Foo" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestPackedTypes), global::Google.Protobuf.TestProtos.TestPackedTypes.Parser, new[]{ "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedEnum" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestUnpackedTypes), global::Google.Protobuf.TestProtos.TestUnpackedTypes.Parser, new[]{ "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedEnum" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes), global::Google.Protobuf.TestProtos.TestRepeatedScalarDifferentTagSizes.Parser, new[]{ "RepeatedFixed32", "RepeatedInt32", "RepeatedFixed64", "RepeatedInt64", "RepeatedFloat", "RepeatedUint64" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestCommentInjectionMessage), global::Google.Protobuf.TestProtos.TestCommentInjectionMessage.Parser, new[]{ "A" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooRequest), global::Google.Protobuf.TestProtos.FooRequest.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooResponse), global::Google.Protobuf.TestProtos.FooResponse.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooClientMessage), global::Google.Protobuf.TestProtos.FooClientMessage.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.FooServerMessage), global::Google.Protobuf.TestProtos.FooServerMessage.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.BarRequest), global::Google.Protobuf.TestProtos.BarRequest.Parser, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.BarResponse), global::Google.Protobuf.TestProtos.BarResponse.Parser, null, null, null, null)
}));
}
#endregion
@@ -193,39 +193,39 @@ namespace Google.Protobuf.TestProtos {
}
#region Enums
public enum ForeignEnum {
- FOREIGN_UNSPECIFIED = 0,
- FOREIGN_FOO = 4,
- FOREIGN_BAR = 5,
- FOREIGN_BAZ = 6,
+ [pbr::OriginalName("FOREIGN_UNSPECIFIED")] ForeignUnspecified = 0,
+ [pbr::OriginalName("FOREIGN_FOO")] ForeignFoo = 4,
+ [pbr::OriginalName("FOREIGN_BAR")] ForeignBar = 5,
+ [pbr::OriginalName("FOREIGN_BAZ")] ForeignBaz = 6,
}
/// <summary>
/// Test an enum that has multiple values with the same number.
/// </summary>
public enum TestEnumWithDupValue {
- TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED = 0,
- FOO1 = 1,
- BAR1 = 2,
- BAZ = 3,
- FOO2 = 1,
- BAR2 = 2,
+ [pbr::OriginalName("TEST_ENUM_WITH_DUP_VALUE_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("FOO1")] Foo1 = 1,
+ [pbr::OriginalName("BAR1")] Bar1 = 2,
+ [pbr::OriginalName("BAZ")] Baz = 3,
+ [pbr::OriginalName("FOO2")] Foo2 = 1,
+ [pbr::OriginalName("BAR2")] Bar2 = 2,
}
/// <summary>
/// Test an enum with large, unordered values.
/// </summary>
public enum TestSparseEnum {
- TEST_SPARSE_ENUM_UNSPECIFIED = 0,
- SPARSE_A = 123,
- SPARSE_B = 62374,
- SPARSE_C = 12589234,
- SPARSE_D = -15,
- SPARSE_E = -53452,
+ [pbr::OriginalName("TEST_SPARSE_ENUM_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("SPARSE_A")] SparseA = 123,
+ [pbr::OriginalName("SPARSE_B")] SparseB = 62374,
+ [pbr::OriginalName("SPARSE_C")] SparseC = 12589234,
+ [pbr::OriginalName("SPARSE_D")] SparseD = -15,
+ [pbr::OriginalName("SPARSE_E")] SparseE = -53452,
/// <summary>
/// In proto3, value 0 must be the first one specified
/// SPARSE_F = 0;
/// </summary>
- SPARSE_G = 2,
+ [pbr::OriginalName("SPARSE_G")] SparseG = 2,
}
#endregion
@@ -241,7 +241,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestAllTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -459,7 +459,7 @@ namespace Google.Protobuf.TestProtos {
public string SingleString {
get { return singleString_; }
set {
- singleString_ = pb::Preconditions.CheckNotNull(value, "value");
+ singleString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -469,7 +469,7 @@ namespace Google.Protobuf.TestProtos {
public pb::ByteString SingleBytes {
get { return singleBytes_; }
set {
- singleBytes_ = pb::Preconditions.CheckNotNull(value, "value");
+ singleBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -505,7 +505,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_nested_enum" field.</summary>
public const int SingleNestedEnumFieldNumber = 21;
- private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum singleNestedEnum_ = 0;
public global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum SingleNestedEnum {
get { return singleNestedEnum_; }
set {
@@ -515,7 +515,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_foreign_enum" field.</summary>
public const int SingleForeignEnumFieldNumber = 22;
- private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.ForeignEnum singleForeignEnum_ = 0;
public global::Google.Protobuf.TestProtos.ForeignEnum SingleForeignEnum {
get { return singleForeignEnum_; }
set {
@@ -525,7 +525,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "single_import_enum" field.</summary>
public const int SingleImportEnumFieldNumber = 23;
- private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.ImportEnum singleImportEnum_ = 0;
public global::Google.Protobuf.TestProtos.ImportEnum SingleImportEnum {
get { return singleImportEnum_; }
set {
@@ -775,7 +775,7 @@ namespace Google.Protobuf.TestProtos {
public string OneofString {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofString ? (string) oneofField_ : ""; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofString;
}
}
@@ -785,7 +785,7 @@ namespace Google.Protobuf.TestProtos {
public pb::ByteString OneofBytes {
get { return oneofFieldCase_ == OneofFieldOneofCase.OneofBytes ? (pb::ByteString) oneofField_ : pb::ByteString.Empty; }
set {
- oneofField_ = pb::Preconditions.CheckNotNull(value, "value");
+ oneofField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
oneofFieldCase_ = OneofFieldOneofCase.OneofBytes;
}
}
@@ -868,6 +868,7 @@ namespace Google.Protobuf.TestProtos {
if (!object.Equals(OneofNestedMessage, other.OneofNestedMessage)) return false;
if (OneofString != other.OneofString) return false;
if (OneofBytes != other.OneofBytes) return false;
+ if (OneofFieldCase != other.OneofFieldCase) return false;
return true;
}
@@ -891,9 +892,9 @@ namespace Google.Protobuf.TestProtos {
if (singleNestedMessage_ != null) hash ^= SingleNestedMessage.GetHashCode();
if (singleForeignMessage_ != null) hash ^= SingleForeignMessage.GetHashCode();
if (singleImportMessage_ != null) hash ^= SingleImportMessage.GetHashCode();
- if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) hash ^= SingleNestedEnum.GetHashCode();
- if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= SingleForeignEnum.GetHashCode();
- if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) hash ^= SingleImportEnum.GetHashCode();
+ if (SingleNestedEnum != 0) hash ^= SingleNestedEnum.GetHashCode();
+ if (SingleForeignEnum != 0) hash ^= SingleForeignEnum.GetHashCode();
+ if (SingleImportEnum != 0) hash ^= SingleImportEnum.GetHashCode();
if (singlePublicImportMessage_ != null) hash ^= SinglePublicImportMessage.GetHashCode();
hash ^= repeatedInt32_.GetHashCode();
hash ^= repeatedInt64_.GetHashCode();
@@ -921,11 +922,12 @@ namespace Google.Protobuf.TestProtos {
if (oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage) hash ^= OneofNestedMessage.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.OneofString) hash ^= OneofString.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.OneofBytes) hash ^= OneofBytes.GetHashCode();
+ hash ^= (int) oneofFieldCase_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1001,15 +1003,15 @@ namespace Google.Protobuf.TestProtos {
output.WriteRawTag(162, 1);
output.WriteMessage(SingleImportMessage);
}
- if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
+ if (SingleNestedEnum != 0) {
output.WriteRawTag(168, 1);
output.WriteEnum((int) SingleNestedEnum);
}
- if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (SingleForeignEnum != 0) {
output.WriteRawTag(176, 1);
output.WriteEnum((int) SingleForeignEnum);
}
- if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
+ if (SingleImportEnum != 0) {
output.WriteRawTag(184, 1);
output.WriteEnum((int) SingleImportEnum);
}
@@ -1113,13 +1115,13 @@ namespace Google.Protobuf.TestProtos {
if (singleImportMessage_ != null) {
size += 2 + pb::CodedOutputStream.ComputeMessageSize(SingleImportMessage);
}
- if (SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
+ if (SingleNestedEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleNestedEnum);
}
- if (SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (SingleForeignEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleForeignEnum);
}
- if (SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
+ if (SingleImportEnum != 0) {
size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) SingleImportEnum);
}
if (singlePublicImportMessage_ != null) {
@@ -1229,13 +1231,13 @@ namespace Google.Protobuf.TestProtos {
}
SingleImportMessage.MergeFrom(other.SingleImportMessage);
}
- if (other.SingleNestedEnum != global::Google.Protobuf.TestProtos.TestAllTypes.Types.NestedEnum.NESTED_ENUM_UNSPECIFIED) {
+ if (other.SingleNestedEnum != 0) {
SingleNestedEnum = other.SingleNestedEnum;
}
- if (other.SingleForeignEnum != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (other.SingleForeignEnum != 0) {
SingleForeignEnum = other.SingleForeignEnum;
}
- if (other.SingleImportEnum != global::Google.Protobuf.TestProtos.ImportEnum.IMPORT_ENUM_UNSPECIFIED) {
+ if (other.SingleImportEnum != 0) {
SingleImportEnum = other.SingleImportEnum;
}
if (other.singlePublicImportMessage_ != null) {
@@ -1524,14 +1526,14 @@ namespace Google.Protobuf.TestProtos {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class Types {
public enum NestedEnum {
- NESTED_ENUM_UNSPECIFIED = 0,
- FOO = 1,
- BAR = 2,
- BAZ = 3,
+ [pbr::OriginalName("NESTED_ENUM_UNSPECIFIED")] Unspecified = 0,
+ [pbr::OriginalName("FOO")] Foo = 1,
+ [pbr::OriginalName("BAR")] Bar = 2,
+ [pbr::OriginalName("BAZ")] Baz = 3,
/// <summary>
/// Intentionally negative.
/// </summary>
- NEG = -1,
+ [pbr::OriginalName("NEG")] Neg = -1,
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1598,7 +1600,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1656,7 +1658,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<NestedTestAllTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1734,7 +1736,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1817,7 +1819,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestDeprecatedFields> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1871,7 +1873,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1925,7 +1927,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<ForeignMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[3]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1978,7 +1980,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2028,7 +2030,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestReservedFields> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[4]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[4]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2068,7 +2070,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2107,7 +2109,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestForeignNested> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[5]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[5]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2160,7 +2162,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2219,7 +2221,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestReallyLargeTagNumber> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[6]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[6]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2289,7 +2291,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2353,7 +2355,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestRecursiveMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[7]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[7]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2419,7 +2421,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2492,7 +2494,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestMutualRecursionA> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[8]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[8]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2545,7 +2547,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2601,7 +2603,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestMutualRecursionB> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[9]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[9]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2667,7 +2669,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2741,7 +2743,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestCamelCaseFieldNames> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[10]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[10]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2785,13 +2787,13 @@ namespace Google.Protobuf.TestProtos {
public string StringField {
get { return stringField_; }
set {
- stringField_ = pb::Preconditions.CheckNotNull(value, "value");
+ stringField_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "EnumField" field.</summary>
public const int EnumFieldFieldNumber = 3;
- private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.ForeignEnum enumField_ = 0;
public global::Google.Protobuf.TestProtos.ForeignEnum EnumField {
get { return enumField_; }
set {
@@ -2871,7 +2873,7 @@ namespace Google.Protobuf.TestProtos {
int hash = 1;
if (PrimitiveField != 0) hash ^= PrimitiveField.GetHashCode();
if (StringField.Length != 0) hash ^= StringField.GetHashCode();
- if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) hash ^= EnumField.GetHashCode();
+ if (EnumField != 0) hash ^= EnumField.GetHashCode();
if (messageField_ != null) hash ^= MessageField.GetHashCode();
hash ^= repeatedPrimitiveField_.GetHashCode();
hash ^= repeatedStringField_.GetHashCode();
@@ -2881,7 +2883,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2893,7 +2895,7 @@ namespace Google.Protobuf.TestProtos {
output.WriteRawTag(18);
output.WriteString(StringField);
}
- if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (EnumField != 0) {
output.WriteRawTag(24);
output.WriteEnum((int) EnumField);
}
@@ -2915,7 +2917,7 @@ namespace Google.Protobuf.TestProtos {
if (StringField.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(StringField);
}
- if (EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (EnumField != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumField);
}
if (messageField_ != null) {
@@ -2938,7 +2940,7 @@ namespace Google.Protobuf.TestProtos {
if (other.StringField.Length != 0) {
StringField = other.StringField;
}
- if (other.EnumField != global::Google.Protobuf.TestProtos.ForeignEnum.FOREIGN_UNSPECIFIED) {
+ if (other.EnumField != 0) {
EnumField = other.EnumField;
}
if (other.messageField_ != null) {
@@ -3013,7 +3015,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestFieldOrderings> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[11]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[11]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3043,7 +3045,7 @@ namespace Google.Protobuf.TestProtos {
public string MyString {
get { return myString_; }
set {
- myString_ = pb::Preconditions.CheckNotNull(value, "value");
+ myString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -3105,7 +3107,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3276,7 +3278,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3345,7 +3347,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<SparseEnumMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[12]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[12]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3368,7 +3370,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Field number for the "sparse_enum" field.</summary>
public const int SparseEnumFieldNumber = 1;
- private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED;
+ private global::Google.Protobuf.TestProtos.TestSparseEnum sparseEnum_ = 0;
public global::Google.Protobuf.TestProtos.TestSparseEnum SparseEnum {
get { return sparseEnum_; }
set {
@@ -3393,16 +3395,16 @@ namespace Google.Protobuf.TestProtos {
public override int GetHashCode() {
int hash = 1;
- if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) hash ^= SparseEnum.GetHashCode();
+ if (SparseEnum != 0) hash ^= SparseEnum.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
- if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
+ if (SparseEnum != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) SparseEnum);
}
@@ -3410,7 +3412,7 @@ namespace Google.Protobuf.TestProtos {
public int CalculateSize() {
int size = 0;
- if (SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
+ if (SparseEnum != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) SparseEnum);
}
return size;
@@ -3420,7 +3422,7 @@ namespace Google.Protobuf.TestProtos {
if (other == null) {
return;
}
- if (other.SparseEnum != global::Google.Protobuf.TestProtos.TestSparseEnum.TEST_SPARSE_ENUM_UNSPECIFIED) {
+ if (other.SparseEnum != 0) {
SparseEnum = other.SparseEnum;
}
}
@@ -3451,7 +3453,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<OneString> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[13]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[13]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3478,7 +3480,7 @@ namespace Google.Protobuf.TestProtos {
public string Data {
get { return data_; }
set {
- data_ = pb::Preconditions.CheckNotNull(value, "value");
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -3504,7 +3506,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3554,7 +3556,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<MoreString> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[14]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[14]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3606,7 +3608,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3649,7 +3651,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<OneBytes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[15]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[15]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3676,7 +3678,7 @@ namespace Google.Protobuf.TestProtos {
public pb::ByteString Data {
get { return data_; }
set {
- data_ = pb::Preconditions.CheckNotNull(value, "value");
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -3702,7 +3704,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3752,7 +3754,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<MoreBytes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[16]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[16]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3779,7 +3781,7 @@ namespace Google.Protobuf.TestProtos {
public pb::ByteString Data {
get { return data_; }
set {
- data_ = pb::Preconditions.CheckNotNull(value, "value");
+ data_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -3805,7 +3807,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3858,7 +3860,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<Int32Message> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[17]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[17]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3911,7 +3913,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3961,7 +3963,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<Uint32Message> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[18]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[18]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4014,7 +4016,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4064,7 +4066,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<Int64Message> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[19]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[19]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4117,7 +4119,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4167,7 +4169,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<Uint64Message> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[20]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[20]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4220,7 +4222,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4270,7 +4272,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<BoolMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[21]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[21]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4323,7 +4325,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4376,7 +4378,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestOneof> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[22]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[22]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4423,7 +4425,7 @@ namespace Google.Protobuf.TestProtos {
public string FooString {
get { return fooCase_ == FooOneofCase.FooString ? (string) foo_ : ""; }
set {
- foo_ = pb::Preconditions.CheckNotNull(value, "value");
+ foo_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
fooCase_ = FooOneofCase.FooString;
}
}
@@ -4470,6 +4472,7 @@ namespace Google.Protobuf.TestProtos {
if (FooInt != other.FooInt) return false;
if (FooString != other.FooString) return false;
if (!object.Equals(FooMessage, other.FooMessage)) return false;
+ if (FooCase != other.FooCase) return false;
return true;
}
@@ -4478,11 +4481,12 @@ namespace Google.Protobuf.TestProtos {
if (fooCase_ == FooOneofCase.FooInt) hash ^= FooInt.GetHashCode();
if (fooCase_ == FooOneofCase.FooString) hash ^= FooString.GetHashCode();
if (fooCase_ == FooOneofCase.FooMessage) hash ^= FooMessage.GetHashCode();
+ hash ^= (int) fooCase_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4568,7 +4572,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestPackedTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[23]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[23]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4776,7 +4780,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4928,7 +4932,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestUnpackedTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[24]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[24]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5136,7 +5140,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5284,7 +5288,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestRepeatedScalarDifferentTagSizes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[25]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[25]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5410,7 +5414,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5494,7 +5498,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestCommentInjectionMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[26]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[26]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5524,7 +5528,7 @@ namespace Google.Protobuf.TestProtos {
public string A {
get { return a_; }
set {
- a_ = pb::Preconditions.CheckNotNull(value, "value");
+ a_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -5550,7 +5554,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5603,7 +5607,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<FooRequest> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[27]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[27]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5643,7 +5647,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5679,7 +5683,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<FooResponse> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[28]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[28]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5719,7 +5723,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5755,7 +5759,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<FooClientMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[29]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[29]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5795,7 +5799,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5831,7 +5835,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<FooServerMessage> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[30]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[30]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5871,7 +5875,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5907,7 +5911,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<BarRequest> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[31]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[31]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -5947,7 +5951,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5983,7 +5987,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<BarResponse> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestProto3.Descriptor.MessageTypes[32]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestProto3Reflection.Descriptor.MessageTypes[32]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -6023,7 +6027,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
index bd90ddd8..ae12f4a4 100644
--- a/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
+++ b/csharp/src/Google.Protobuf.Test/TestProtos/UnittestWellKnownTypes.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.TestProtos {
/// <summary>Holder for reflection information generated from google/protobuf/unittest_well_known_types.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class UnittestWellKnownTypes {
+ public static partial class UnittestWellKnownTypesReflection {
#region Descriptor
/// <summary>File descriptor for google/protobuf/unittest_well_known_types.proto</summary>
@@ -20,7 +20,7 @@ namespace Google.Protobuf.TestProtos {
}
private static pbr::FileDescriptor descriptor;
- static UnittestWellKnownTypes() {
+ static UnittestWellKnownTypesReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Ci9nb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfd2VsbF9rbm93bl90eXBlcy5w",
@@ -31,7 +31,7 @@ namespace Google.Protobuf.TestProtos {
"L3Byb3RvYnVmL3NvdXJjZV9jb250ZXh0LnByb3RvGhxnb29nbGUvcHJvdG9i",
"dWYvc3RydWN0LnByb3RvGh9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnBy",
"b3RvGhpnb29nbGUvcHJvdG9idWYvdHlwZS5wcm90bxoeZ29vZ2xlL3Byb3Rv",
- "YnVmL3dyYXBwZXJzLnByb3RvIpEHChJUZXN0V2VsbEtub3duVHlwZXMSJwoJ",
+ "YnVmL3dyYXBwZXJzLnByb3RvIr4HChJUZXN0V2VsbEtub3duVHlwZXMSJwoJ",
"YW55X2ZpZWxkGAEgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFueRInCglhcGlf",
"ZmllbGQYAiABKAsyFC5nb29nbGUucHJvdG9idWYuQXBpEjEKDmR1cmF0aW9u",
"X2ZpZWxkGAMgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uEisKC2Vt",
@@ -51,7 +51,8 @@ namespace Google.Protobuf.TestProtos {
"cm90b2J1Zi5VSW50MzJWYWx1ZRIuCgpib29sX2ZpZWxkGBAgASgLMhouZ29v",
"Z2xlLnByb3RvYnVmLkJvb2xWYWx1ZRIyCgxzdHJpbmdfZmllbGQYESABKAsy",
"HC5nb29nbGUucHJvdG9idWYuU3RyaW5nVmFsdWUSMAoLYnl0ZXNfZmllbGQY",
- "EiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZSKVBwoWUmVwZWF0",
+ "EiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZRIrCgt2YWx1ZV9m",
+ "aWVsZBgTIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSKVBwoWUmVwZWF0",
"ZWRXZWxsS25vd25UeXBlcxInCglhbnlfZmllbGQYASADKAsyFC5nb29nbGUu",
"cHJvdG9idWYuQW55EicKCWFwaV9maWVsZBgCIAMoCzIULmdvb2dsZS5wcm90",
"b2J1Zi5BcGkSMQoOZHVyYXRpb25fZmllbGQYAyADKAsyGS5nb29nbGUucHJv",
@@ -159,13 +160,13 @@ namespace Google.Protobuf.TestProtos {
"AiABKAsyGy5nb29nbGUucHJvdG9idWYuQnl0ZXNWYWx1ZToCOAFCOQoYY29t",
"Lmdvb2dsZS5wcm90b2J1Zi50ZXN0UAGqAhpHb29nbGUuUHJvdG9idWYuVGVz",
"dFByb3Rvc2IGcHJvdG8z"));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.Proto.Any.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.Api.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.Duration.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.Empty.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.FieldMask.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.SourceContext.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.Struct.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.Timestamp.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.Type.Descriptor, global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor, },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.TestWellKnownTypes), new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes), new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.OneofWellKnownTypes), new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, new[]{ "OneofField" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.TestProtos.MapWellKnownTypes), new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, new pbr::GeneratedCodeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, })
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.TestWellKnownTypes), global::Google.Protobuf.TestProtos.TestWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField", "ValueField" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes), global::Google.Protobuf.TestProtos.RepeatedWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.OneofWellKnownTypes), global::Google.Protobuf.TestProtos.OneofWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, new[]{ "OneofField" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.TestProtos.MapWellKnownTypes), global::Google.Protobuf.TestProtos.MapWellKnownTypes.Parser, new[]{ "AnyField", "ApiField", "DurationField", "EmptyField", "FieldMaskField", "SourceContextField", "StructField", "TimestampField", "TypeField", "DoubleField", "FloatField", "Int64Field", "Uint64Field", "Int32Field", "Uint32Field", "BoolField", "StringField", "BytesField" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, })
}));
}
#endregion
@@ -183,7 +184,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<TestWellKnownTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypes.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -215,6 +216,7 @@ namespace Google.Protobuf.TestProtos {
BoolField = other.BoolField;
StringField = other.StringField;
BytesField = other.BytesField;
+ ValueField = other.valueField_ != null ? other.ValueField.Clone() : null;
}
public TestWellKnownTypes Clone() {
@@ -410,6 +412,19 @@ namespace Google.Protobuf.TestProtos {
}
}
+ /// <summary>Field number for the "value_field" field.</summary>
+ public const int ValueFieldFieldNumber = 19;
+ private global::Google.Protobuf.WellKnownTypes.Value valueField_;
+ /// <summary>
+ /// Part of struct, but useful to be able to test separately
+ /// </summary>
+ public global::Google.Protobuf.WellKnownTypes.Value ValueField {
+ get { return valueField_; }
+ set {
+ valueField_ = value;
+ }
+ }
+
public override bool Equals(object other) {
return Equals(other as TestWellKnownTypes);
}
@@ -439,6 +454,7 @@ namespace Google.Protobuf.TestProtos {
if (BoolField != other.BoolField) return false;
if (StringField != other.StringField) return false;
if (BytesField != other.BytesField) return false;
+ if (!object.Equals(ValueField, other.ValueField)) return false;
return true;
}
@@ -462,11 +478,12 @@ namespace Google.Protobuf.TestProtos {
if (boolField_ != null) hash ^= BoolField.GetHashCode();
if (stringField_ != null) hash ^= StringField.GetHashCode();
if (bytesField_ != null) hash ^= BytesField.GetHashCode();
+ if (valueField_ != null) hash ^= ValueField.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -533,6 +550,10 @@ namespace Google.Protobuf.TestProtos {
if (bytesField_ != null) {
_single_bytesField_codec.WriteTagAndValue(output, BytesField);
}
+ if (valueField_ != null) {
+ output.WriteRawTag(154, 1);
+ output.WriteMessage(ValueField);
+ }
}
public int CalculateSize() {
@@ -591,6 +612,9 @@ namespace Google.Protobuf.TestProtos {
if (bytesField_ != null) {
size += _single_bytesField_codec.CalculateSizeWithTag(BytesField);
}
+ if (valueField_ != null) {
+ size += 2 + pb::CodedOutputStream.ComputeMessageSize(ValueField);
+ }
return size;
}
@@ -697,6 +721,12 @@ namespace Google.Protobuf.TestProtos {
BytesField = other.BytesField;
}
}
+ if (other.valueField_ != null) {
+ if (valueField_ == null) {
+ valueField_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ ValueField.MergeFrom(other.ValueField);
+ }
}
public void MergeFrom(pb::CodedInputStream input) {
@@ -832,6 +862,13 @@ namespace Google.Protobuf.TestProtos {
}
break;
}
+ case 154: {
+ if (valueField_ == null) {
+ valueField_ = new global::Google.Protobuf.WellKnownTypes.Value();
+ }
+ input.ReadMessage(valueField_);
+ break;
+ }
}
}
}
@@ -847,7 +884,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<RepeatedWellKnownTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypes.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1106,7 +1143,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1268,7 +1305,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<OneofWellKnownTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypes.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1596,6 +1633,7 @@ namespace Google.Protobuf.TestProtos {
if (BoolField != other.BoolField) return false;
if (StringField != other.StringField) return false;
if (BytesField != other.BytesField) return false;
+ if (OneofFieldCase != other.OneofFieldCase) return false;
return true;
}
@@ -1619,11 +1657,12 @@ namespace Google.Protobuf.TestProtos {
if (oneofFieldCase_ == OneofFieldOneofCase.BoolField) hash ^= BoolField.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.StringField) hash ^= StringField.GetHashCode();
if (oneofFieldCase_ == OneofFieldOneofCase.BytesField) hash ^= BytesField.GetHashCode();
+ hash ^= (int) oneofFieldCase_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1955,7 +1994,7 @@ namespace Google.Protobuf.TestProtos {
public static pb::MessageParser<MapWellKnownTypes> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypes.Descriptor.MessageTypes[3]; }
+ get { return global::Google.Protobuf.TestProtos.UnittestWellKnownTypesReflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2078,7 +2117,7 @@ namespace Google.Protobuf.TestProtos {
public const int DoubleFieldFieldNumber = 10;
private static readonly pbc::MapField<int, double?>.Codec _map_doubleField_codec
= new pbc::MapField<int, double?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<double>(18), 82);
- private readonly pbc::MapField<int, double?> doubleField_ = new pbc::MapField<int, double?>(true);
+ private readonly pbc::MapField<int, double?> doubleField_ = new pbc::MapField<int, double?>();
public pbc::MapField<int, double?> DoubleField {
get { return doubleField_; }
}
@@ -2087,7 +2126,7 @@ namespace Google.Protobuf.TestProtos {
public const int FloatFieldFieldNumber = 11;
private static readonly pbc::MapField<int, float?>.Codec _map_floatField_codec
= new pbc::MapField<int, float?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<float>(18), 90);
- private readonly pbc::MapField<int, float?> floatField_ = new pbc::MapField<int, float?>(true);
+ private readonly pbc::MapField<int, float?> floatField_ = new pbc::MapField<int, float?>();
public pbc::MapField<int, float?> FloatField {
get { return floatField_; }
}
@@ -2096,7 +2135,7 @@ namespace Google.Protobuf.TestProtos {
public const int Int64FieldFieldNumber = 12;
private static readonly pbc::MapField<int, long?>.Codec _map_int64Field_codec
= new pbc::MapField<int, long?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<long>(18), 98);
- private readonly pbc::MapField<int, long?> int64Field_ = new pbc::MapField<int, long?>(true);
+ private readonly pbc::MapField<int, long?> int64Field_ = new pbc::MapField<int, long?>();
public pbc::MapField<int, long?> Int64Field {
get { return int64Field_; }
}
@@ -2105,7 +2144,7 @@ namespace Google.Protobuf.TestProtos {
public const int Uint64FieldFieldNumber = 13;
private static readonly pbc::MapField<int, ulong?>.Codec _map_uint64Field_codec
= new pbc::MapField<int, ulong?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<ulong>(18), 106);
- private readonly pbc::MapField<int, ulong?> uint64Field_ = new pbc::MapField<int, ulong?>(true);
+ private readonly pbc::MapField<int, ulong?> uint64Field_ = new pbc::MapField<int, ulong?>();
public pbc::MapField<int, ulong?> Uint64Field {
get { return uint64Field_; }
}
@@ -2114,7 +2153,7 @@ namespace Google.Protobuf.TestProtos {
public const int Int32FieldFieldNumber = 14;
private static readonly pbc::MapField<int, int?>.Codec _map_int32Field_codec
= new pbc::MapField<int, int?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<int>(18), 114);
- private readonly pbc::MapField<int, int?> int32Field_ = new pbc::MapField<int, int?>(true);
+ private readonly pbc::MapField<int, int?> int32Field_ = new pbc::MapField<int, int?>();
public pbc::MapField<int, int?> Int32Field {
get { return int32Field_; }
}
@@ -2123,7 +2162,7 @@ namespace Google.Protobuf.TestProtos {
public const int Uint32FieldFieldNumber = 15;
private static readonly pbc::MapField<int, uint?>.Codec _map_uint32Field_codec
= new pbc::MapField<int, uint?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<uint>(18), 122);
- private readonly pbc::MapField<int, uint?> uint32Field_ = new pbc::MapField<int, uint?>(true);
+ private readonly pbc::MapField<int, uint?> uint32Field_ = new pbc::MapField<int, uint?>();
public pbc::MapField<int, uint?> Uint32Field {
get { return uint32Field_; }
}
@@ -2132,7 +2171,7 @@ namespace Google.Protobuf.TestProtos {
public const int BoolFieldFieldNumber = 16;
private static readonly pbc::MapField<int, bool?>.Codec _map_boolField_codec
= new pbc::MapField<int, bool?>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForStructWrapper<bool>(18), 130);
- private readonly pbc::MapField<int, bool?> boolField_ = new pbc::MapField<int, bool?>(true);
+ private readonly pbc::MapField<int, bool?> boolField_ = new pbc::MapField<int, bool?>();
public pbc::MapField<int, bool?> BoolField {
get { return boolField_; }
}
@@ -2141,7 +2180,7 @@ namespace Google.Protobuf.TestProtos {
public const int StringFieldFieldNumber = 17;
private static readonly pbc::MapField<int, string>.Codec _map_stringField_codec
= new pbc::MapField<int, string>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper<string>(18), 138);
- private readonly pbc::MapField<int, string> stringField_ = new pbc::MapField<int, string>(true);
+ private readonly pbc::MapField<int, string> stringField_ = new pbc::MapField<int, string>();
public pbc::MapField<int, string> StringField {
get { return stringField_; }
}
@@ -2150,7 +2189,7 @@ namespace Google.Protobuf.TestProtos {
public const int BytesFieldFieldNumber = 18;
private static readonly pbc::MapField<int, pb::ByteString>.Codec _map_bytesField_codec
= new pbc::MapField<int, pb::ByteString>.Codec(pb::FieldCodec.ForInt32(8), pb::FieldCodec.ForClassWrapper<pb::ByteString>(18), 146);
- private readonly pbc::MapField<int, pb::ByteString> bytesField_ = new pbc::MapField<int, pb::ByteString>(true);
+ private readonly pbc::MapField<int, pb::ByteString> bytesField_ = new pbc::MapField<int, pb::ByteString>();
public pbc::MapField<int, pb::ByteString> BytesField {
get { return bytesField_; }
}
@@ -2211,7 +2250,7 @@ namespace Google.Protobuf.TestProtos {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
index 0a2b8b32..f21be7d9 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/AnyTest.cs
@@ -47,6 +47,24 @@ namespace Google.Protobuf.WellKnownTypes
}
[Test]
+ public void Pack_WithCustomPrefix()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message, "foo.bar/baz");
+ Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
+ Assert.AreEqual(message.CalculateSize(), any.Value.Length);
+ }
+
+ [Test]
+ public void Pack_WithCustomPrefixTrailingSlash()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message, "foo.bar/baz/");
+ Assert.AreEqual("foo.bar/baz/protobuf_unittest.TestAllTypes", any.TypeUrl);
+ Assert.AreEqual(message.CalculateSize(), any.Value.Length);
+ }
+
+ [Test]
public void Unpack_WrongType()
{
var message = SampleMessages.CreateFullTestAllTypes();
@@ -62,5 +80,37 @@ namespace Google.Protobuf.WellKnownTypes
var unpacked = any.Unpack<TestAllTypes>();
Assert.AreEqual(message, unpacked);
}
+
+ [Test]
+ public void Unpack_CustomPrefix_Success()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message, "foo.bar/baz");
+ var unpacked = any.Unpack<TestAllTypes>();
+ Assert.AreEqual(message, unpacked);
+ }
+
+ [Test]
+ public void ToString_WithValues()
+ {
+ var message = SampleMessages.CreateFullTestAllTypes();
+ var any = Any.Pack(message);
+ var text = any.ToString();
+ Assert.That(text, Is.StringContaining("\"@value\": \"" + message.ToByteString().ToBase64() + "\""));
+ }
+
+ [Test]
+ public void ToString_Empty()
+ {
+ var any = new Any();
+ Assert.AreEqual("{ \"@type\": \"\", \"@value\": \"\" }", any.ToString());
+ }
+
+ [Test]
+ public void ToString_MessageContainingAny()
+ {
+ var message = new TestWellKnownTypes { AnyField = new Any() };
+ Assert.AreEqual("{ \"anyField\": { \"@type\": \"\", \"@value\": \"\" } }", message.ToString());
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
index 36012e63..141faf80 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/DurationTest.cs
@@ -50,11 +50,6 @@ namespace Google.Protobuf.WellKnownTypes
// Rounding is towards 0
Assert.AreEqual(TimeSpan.FromTicks(2), new Duration { Nanos = 250 }.ToTimeSpan());
Assert.AreEqual(TimeSpan.FromTicks(-2), new Duration { Nanos = -250 }.ToTimeSpan());
-
- // Non-normalized durations
- Assert.AreEqual(TimeSpan.FromSeconds(3), new Duration { Seconds = 1, Nanos = 2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
- Assert.AreEqual(TimeSpan.FromSeconds(1), new Duration { Seconds = 3, Nanos = -2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
- Assert.AreEqual(TimeSpan.FromSeconds(-1), new Duration { Seconds = 1, Nanos = -2 * Duration.NanosecondsPerSecond }.ToTimeSpan());
}
[Test]
@@ -100,5 +95,38 @@ namespace Google.Protobuf.WellKnownTypes
Assert.AreEqual(new Duration { Seconds = 1 }, Duration.FromTimeSpan(TimeSpan.FromSeconds(1)));
Assert.AreEqual(new Duration { Nanos = Duration.NanosecondsPerTick }, Duration.FromTimeSpan(TimeSpan.FromTicks(1)));
}
+
+ [Test]
+ [TestCase(0, Duration.MaxNanoseconds + 1)]
+ [TestCase(0, Duration.MinNanoseconds - 1)]
+ [TestCase(Duration.MinSeconds - 1, 0)]
+ [TestCase(Duration.MaxSeconds + 1, 0)]
+ [TestCase(1, -1)]
+ [TestCase(-1, 1)]
+ public void ToTimeSpan_Invalid(long seconds, int nanoseconds)
+ {
+ var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => duration.ToTimeSpan());
+ }
+
+ [Test]
+ [TestCase(0, Duration.MaxNanoseconds)]
+ [TestCase(0, Duration.MinNanoseconds)]
+ [TestCase(Duration.MinSeconds, Duration.MinNanoseconds)]
+ [TestCase(Duration.MaxSeconds, Duration.MaxNanoseconds)]
+ public void ToTimeSpan_Valid(long seconds, int nanoseconds)
+ {
+ // Only testing that these values don't throw, unlike their similar tests in ToTimeSpan_Invalid
+ var duration = new Duration { Seconds = seconds, Nanos = nanoseconds };
+ duration.ToTimeSpan();
+ }
+
+ [Test]
+ public void ToString_NonNormalized()
+ {
+ // Just a single example should be sufficient...
+ var duration = new Duration { Seconds = 1, Nanos = -1 };
+ Assert.AreEqual("{ \"@warning\": \"Invalid Duration\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs
new file mode 100644
index 00000000..89bc8275
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/FieldMaskTest.cs
@@ -0,0 +1,62 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+#endregion
+
+
+using NUnit.Framework;
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ public class FieldMaskTest
+ {
+ [Test]
+ [TestCase("foo__bar")]
+ [TestCase("foo_3_ar")]
+ [TestCase("fooBar")]
+ public void ToString_Invalid(string input)
+ {
+ var mask = new FieldMask { Paths = { input } };
+ var text = mask.ToString();
+ // More specific test below
+ Assert.That(text, Is.StringContaining("@warning"));
+ Assert.That(text, Is.StringContaining(input));
+ }
+
+ [Test]
+ public void ToString_Invalid_Precise()
+ {
+ var mask = new FieldMask { Paths = { "x", "foo__bar", @"x\y" } };
+ Assert.AreEqual(
+ "{ \"@warning\": \"Invalid FieldMask\", \"paths\": [ \"x\", \"foo__bar\", \"x\\\\y\" ] }",
+ mask.ToString());
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
index 597539eb..9ecd24c6 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/TimestampTest.cs
@@ -61,6 +61,29 @@ namespace Google.Protobuf.WellKnownTypes
Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 59).AddMilliseconds(1), t2.ToDateTime());
}
+ [Test]
+ [TestCase(Timestamp.UnixSecondsAtBclMinValue - 1, Timestamp.MaxNanos)]
+ [TestCase(Timestamp.UnixSecondsAtBclMaxValue + 1, 0)]
+ [TestCase(0, -1)]
+ [TestCase(0, Timestamp.MaxNanos + 1)]
+ public void ToDateTime_OutOfRange(long seconds, int nanoseconds)
+ {
+ var value = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
+ Assert.Throws<InvalidOperationException>(() => value.ToDateTime());
+ }
+
+ // 1ns larger or smaller than the above values
+ [Test]
+ [TestCase(Timestamp.UnixSecondsAtBclMinValue, 0)]
+ [TestCase(Timestamp.UnixSecondsAtBclMaxValue, Timestamp.MaxNanos)]
+ [TestCase(0, 0)]
+ [TestCase(0, Timestamp.MaxNanos)]
+ public void ToDateTime_ValidBoundaries(long seconds, int nanoseconds)
+ {
+ var value = new Timestamp { Seconds = seconds, Nanos = nanoseconds };
+ value.ToDateTime();
+ }
+
private static void AssertRoundtrip(Timestamp timestamp, DateTime dateTime)
{
Assert.AreEqual(timestamp, Timestamp.FromDateTime(dateTime));
@@ -80,5 +103,13 @@ namespace Google.Protobuf.WellKnownTypes
Assert.AreEqual(t1, t2 + difference);
Assert.AreEqual(t2, t1 - difference);
}
+
+ [Test]
+ public void ToString_NonNormalized()
+ {
+ // Just a single example should be sufficient...
+ var duration = new Timestamp { Seconds = 1, Nanos = -1 };
+ Assert.AreEqual("{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"1\", \"nanos\": -1 }", duration.ToString());
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
index fbc0ff07..5b7185dc 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
@@ -149,8 +149,34 @@ namespace Google.Protobuf.WellKnownTypes
}
[Test]
+ public void RepeatedWrappersBinaryFormat()
+ {
+ // At one point we accidentally used a packed format for repeated wrappers, which is wrong (and weird).
+ // This test is just to prove that we use the right format.
+
+ var rawOutput = new MemoryStream();
+ var output = new CodedOutputStream(rawOutput);
+ // Write a value of 5
+ output.WriteTag(RepeatedWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(2);
+ output.WriteTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint);
+ output.WriteInt32(5);
+ // Write a value of 0 (empty message)
+ output.WriteTag(RepeatedWellKnownTypes.Int32FieldFieldNumber, WireFormat.WireType.LengthDelimited);
+ output.WriteLength(0);
+ output.Flush();
+ var expectedBytes = rawOutput.ToArray();
+
+ var message = new RepeatedWellKnownTypes { Int32Field = { 5, 0 } };
+ var actualBytes = message.ToByteArray();
+ Assert.AreEqual(expectedBytes, actualBytes);
+ }
+
+ [Test]
public void MapWrappersSerializeDeserialize()
{
+ // Note: no null values here, as they are prohibited in map fields
+ // (despite being representable).
var message = new MapWellKnownTypes
{
BoolField = { { 10, false }, { 20, true } },
@@ -158,13 +184,12 @@ namespace Google.Protobuf.WellKnownTypes
{ -1, ByteString.CopyFrom(1, 2, 3) },
{ 10, ByteString.CopyFrom(4, 5, 6) },
{ 1000, ByteString.Empty },
- { 10000, null }
},
DoubleField = { { 1, 12.5 }, { 10, -1.5 }, { 20, 0d } },
FloatField = { { 2, 123.25f }, { 3, -20f }, { 4, 0f } },
Int32Field = { { 5, int.MaxValue }, { 6, int.MinValue }, { 7, 0 } },
Int64Field = { { 8, long.MaxValue }, { 9, long.MinValue }, { 10, 0L } },
- StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" }, { 14, null } },
+ StringField = { { 11, "First" }, { 12, "Second" }, { 13, "" } },
Uint32Field = { { 15, uint.MaxValue }, { 16, uint.MinValue }, { 17, 0U } },
Uint64Field = { { 18, ulong.MaxValue }, { 19, ulong.MinValue }, { 20, 0UL } },
};
@@ -224,13 +249,11 @@ namespace Google.Protobuf.WellKnownTypes
[Test]
public void Reflection_MapFields()
{
- // Just a single example... note that we can't have a null value here
- var message = new MapWellKnownTypes { Int32Field = { { 1, 2 }, { 3, null } } };
+ // Just a single example... note that we can't have a null value here despite the value type being int?
+ var message = new MapWellKnownTypes { Int32Field = { { 1, 2 } } };
var fields = MapWellKnownTypes.Descriptor.Fields;
var dictionary = (IDictionary) fields[MapWellKnownTypes.Int32FieldFieldNumber].Accessor.GetValue(message);
Assert.AreEqual(2, dictionary[1]);
- Assert.IsNull(dictionary[3]);
- Assert.IsTrue(dictionary.Contains(3));
}
[Test]
@@ -296,9 +319,10 @@ namespace Google.Protobuf.WellKnownTypes
// Merging is odd with wrapper types, due to the way that default values aren't emitted in
// the binary stream. In fact we cheat a little bit - a message with an explicitly present default
- // value will have that default value ignored.
+ // value will have that default value ignored. See issue 615. Fixing this would require significant upheaval to
+ // the FieldCodec side of things.
[Test]
- public void MergingCornerCase()
+ public void MergingStreamExplicitValue()
{
var message = new TestWellKnownTypes { Int32Field = 5 };
@@ -320,9 +344,47 @@ namespace Google.Protobuf.WellKnownTypes
message.MergeFrom(bytes);
// A normal implementation would have 0 now, as the explicit default would have been overwritten the 5.
+ // With the FieldCodec for Nullable<int>, we can't tell the difference between an implicit 0 and an explicit 0.
+ Assert.AreEqual(5, message.Int32Field);
+ }
+
+ [Test]
+ public void MergingStreamNoValue()
+ {
+ var message = new TestWellKnownTypes { Int32Field = 5 };
+
+ // Create a byte array which an Int32 field, but with no value.
+ var bytes = new TestWellKnownTypes { Int32Field = 0 }.ToByteArray();
+ Assert.AreEqual(2, bytes.Length); // The tag for Int32Field is a single byte, then a byte indicating a 0-length message.
+ message.MergeFrom(bytes);
+
+ // The "implicit" 0 did *not* overwrite the value.
+ // (This is the correct behaviour.)
Assert.AreEqual(5, message.Int32Field);
}
+ // All permutations of origin/merging value being null, zero (default) or non-default.
+ // As this is the in-memory version, we don't need to worry about the difference between implicit and explicit 0.
+ [Test]
+ [TestCase(null, null, null)]
+ [TestCase(null, 0, 0)]
+ [TestCase(null, 5, 5)]
+ [TestCase(0, null, 0)]
+ [TestCase(0, 0, 0)]
+ [TestCase(0, 5, 5)]
+ [TestCase(5, null, 5)]
+ [TestCase(5, 0, 5)]
+ [TestCase(5, 10, 10)]
+ public void MergingMessageWithZero(int? originValue, int? mergingValue, int? expectedResult)
+ {
+ // This differs from the MergingStreamCornerCase because when we merge message *objects*,
+ // we ignore default values from the "source".
+ var message1 = new TestWellKnownTypes { Int32Field = originValue };
+ var message2 = new TestWellKnownTypes { Int32Field = mergingValue };
+ message1.MergeFrom(message2);
+ Assert.AreEqual(expectedResult, message1.Int32Field);
+ }
+
[Test]
public void UnknownFieldInWrapper()
{
@@ -345,5 +407,15 @@ namespace Google.Protobuf.WellKnownTypes
var message = TestWellKnownTypes.Parser.ParseFrom(stream);
Assert.AreEqual(6, message.Int32Field);
}
+
+ [Test]
+ public void ClearWithReflection()
+ {
+ // String and Bytes are the tricky ones here, as the CLR type of the property
+ // is the same between the wrapper and non-wrapper types.
+ var message = new TestWellKnownTypes { StringField = "foo" };
+ TestWellKnownTypes.Descriptor.Fields[TestWellKnownTypes.StringFieldFieldNumber].Accessor.Clear(message);
+ Assert.IsNull(message.StringField);
+ }
}
}
diff --git a/csharp/src/Google.Protobuf.sln b/csharp/src/Google.Protobuf.sln
index 69ce9a47..72d87f76 100644
--- a/csharp/src/Google.Protobuf.sln
+++ b/csharp/src/Google.Protobuf.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
-MinimumVisualStudioVersion = 10.0.40219.1
+# Visual Studio 2015
+VisualStudioVersion = 14.0.24720.0
+MinimumVisualStudioVersion = 14.0.24720.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf", "Google.Protobuf\Google.Protobuf.csproj", "{6908BDCE-D925-43F3-94AC-A531E6DF2591}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Google.Protobuf.Test", "Google.Protobuf.Test\Google.Protobuf.Test.csproj", "{DD01ED24-3750-4567-9A23-1DB676A15610}"
diff --git a/csharp/src/Google.Protobuf/ByteString.cs b/csharp/src/Google.Protobuf/ByteString.cs
index 3d55f02d..dd7f22d6 100644
--- a/csharp/src/Google.Protobuf/ByteString.cs
+++ b/csharp/src/Google.Protobuf/ByteString.cs
@@ -50,13 +50,13 @@ namespace Google.Protobuf
/// <summary>
/// Unsafe operations that can cause IO Failure and/or other catestrophic side-effects.
/// </summary>
- public static class Unsafe
+ internal static class Unsafe
{
/// <summary>
/// Constructs a new ByteString from the given byte array. The array is
/// *not* copied, and must not be modified after this constructor is called.
/// </summary>
- public static ByteString FromBytes(byte[] bytes)
+ internal static ByteString FromBytes(byte[] bytes)
{
return new ByteString(bytes);
}
@@ -65,7 +65,7 @@ namespace Google.Protobuf
/// Provides direct, unrestricted access to the bytes contained in this instance.
/// You must not modify or resize the byte array returned by this method.
/// </summary>
- public static byte[] GetBuffer(ByteString bytes)
+ internal static byte[] GetBuffer(ByteString bytes)
{
return bytes.bytes;
}
diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs
index 65d0e710..ce6856d6 100644
--- a/csharp/src/Google.Protobuf/CodedInputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedInputStream.cs
@@ -51,9 +51,15 @@ namespace Google.Protobuf
/// and <see cref="MapField{TKey, TValue}"/> to serialize such fields.
/// </para>
/// </remarks>
- public sealed class CodedInputStream
+ public sealed class CodedInputStream : IDisposable
{
/// <summary>
+ /// Whether to leave the underlying stream open when disposing of this stream.
+ /// This is always true when there's no stream.
+ /// </summary>
+ private readonly bool leaveOpen;
+
+ /// <summary>
/// Buffer of data read from the stream or provided at construction time.
/// </summary>
private readonly byte[] buffer;
@@ -115,15 +121,15 @@ namespace Google.Protobuf
/// <summary>
/// Creates a new CodedInputStream reading data from the given byte array.
/// </summary>
- public CodedInputStream(byte[] buffer) : this(null, Preconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length)
+ public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length)
{
}
/// <summary>
- /// Creates a new CodedInputStream that reads from the given byte array slice.
+ /// Creates a new <see cref="CodedInputStream"/> that reads from the given byte array slice.
/// </summary>
public CodedInputStream(byte[] buffer, int offset, int length)
- : this(null, Preconditions.CheckNotNull(buffer, "buffer"), offset, offset + length)
+ : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length)
{
if (offset < 0 || offset > buffer.Length)
{
@@ -136,14 +142,28 @@ namespace Google.Protobuf
}
/// <summary>
- /// Creates a new CodedInputStream reading data from the given stream.
+ /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream, which will be disposed
+ /// when the returned object is disposed.
/// </summary>
- public CodedInputStream(Stream input) : this(input, new byte[BufferSize], 0, 0)
+ /// <param name="input">The stream to read from.</param>
+ public CodedInputStream(Stream input) : this(input, false)
{
- Preconditions.CheckNotNull(input, "input");
}
/// <summary>
+ /// Creates a new <see cref="CodedInputStream"/> reading data from the given stream.
+ /// </summary>
+ /// <param name="input">The stream to read from.</param>
+ /// <param name="leaveOpen"><c>true</c> to leave <paramref name="input"/> open when the returned
+ /// <c cref="CodedInputStream"/> is disposed; <c>false</c> to dispose of the given stream when the
+ /// returned object is disposed.</param>
+ public CodedInputStream(Stream input, bool leaveOpen)
+ : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[BufferSize], 0, 0)
+ {
+ this.leaveOpen = leaveOpen;
+ }
+
+ /// <summary>
/// Creates a new CodedInputStream reading data from the given
/// stream and buffer, using the default limits.
/// </summary>
@@ -246,6 +266,22 @@ namespace Google.Protobuf
/// </value>
public int RecursionLimit { get { return recursionLimit; } }
+ /// <summary>
+ /// Disposes of this instance, potentially closing any underlying stream.
+ /// </summary>
+ /// <remarks>
+ /// As there is no flushing to perform here, disposing of a <see cref="CodedInputStream"/> which
+ /// was constructed with the <c>leaveOpen</c> option parameter set to <c>true</c> (or one which
+ /// was constructed to read from a byte array) has no effect.
+ /// </remarks>
+ public void Dispose()
+ {
+ if (!leaveOpen)
+ {
+ input.Dispose();
+ }
+ }
+
#region Validation
/// <summary>
/// Verifies that the last call to ReadTag() returned tag 0 - in other words,
@@ -349,6 +385,14 @@ namespace Google.Protobuf
/// This should be called directly after <see cref="ReadTag"/>, when
/// the caller wishes to skip an unknown field.
/// </summary>
+ /// <remarks>
+ /// This method throws <see cref="InvalidProtocolBufferException"/> if the last-read tag was an end-group tag.
+ /// If a caller wishes to skip a group, they should skip the whole group, by calling this method after reading the
+ /// start-group tag. This behavior allows callers to call this method on any field they don't understand, correctly
+ /// resulting in an error if an end-group tag has not been paired with an earlier start-group tag.
+ /// </remarks>
+ /// <exception cref="InvalidProtocolBufferException">The last tag was an end-group tag</exception>
+ /// <exception cref="InvalidOperationException">The last read operation read to the end of the logical stream</exception>
public void SkipLastField()
{
if (lastTag == 0)
@@ -358,11 +402,11 @@ namespace Google.Protobuf
switch (WireFormat.GetTagWireType(lastTag))
{
case WireFormat.WireType.StartGroup:
- SkipGroup();
+ SkipGroup(lastTag);
break;
case WireFormat.WireType.EndGroup:
- // Just ignore; there's no data following the tag.
- break;
+ throw new InvalidProtocolBufferException(
+ "SkipLastField called on an end-group tag, indicating that the corresponding start-group was missing");
case WireFormat.WireType.Fixed32:
ReadFixed32();
break;
@@ -379,7 +423,7 @@ namespace Google.Protobuf
}
}
- private void SkipGroup()
+ private void SkipGroup(uint startGroupTag)
{
// Note: Currently we expect this to be the way that groups are read. We could put the recursion
// depth changes into the ReadTag method instead, potentially...
@@ -389,16 +433,28 @@ namespace Google.Protobuf
throw InvalidProtocolBufferException.RecursionLimitExceeded();
}
uint tag;
- do
+ while (true)
{
tag = ReadTag();
if (tag == 0)
{
throw InvalidProtocolBufferException.TruncatedMessage();
}
+ // Can't call SkipLastField for this case- that would throw.
+ if (WireFormat.GetTagWireType(tag) == WireFormat.WireType.EndGroup)
+ {
+ break;
+ }
// This recursion will allow us to handle nested groups.
SkipLastField();
- } while (WireFormat.GetTagWireType(tag) != WireFormat.WireType.EndGroup);
+ }
+ int startField = WireFormat.GetTagFieldNumber(startGroupTag);
+ int endField = WireFormat.GetTagFieldNumber(tag);
+ if (startField != endField)
+ {
+ throw new InvalidProtocolBufferException(
+ $"Mismatched end-group tag. Started with field {startField}; ended with field {endField}");
+ }
recursionDepth--;
}
diff --git a/csharp/src/Google.Protobuf/CodedOutputStream.cs b/csharp/src/Google.Protobuf/CodedOutputStream.cs
index d6355f03..6211aac3 100644
--- a/csharp/src/Google.Protobuf/CodedOutputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedOutputStream.cs
@@ -55,7 +55,7 @@ namespace Google.Protobuf
/// and <c>MapField&lt;TKey, TValue&gt;</c> to serialize such fields.
/// </para>
/// </remarks>
- public sealed partial class CodedOutputStream
+ public sealed partial class CodedOutputStream : IDisposable
{
// "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a difference.)
internal static readonly Encoding Utf8Encoding = Encoding.UTF8;
@@ -65,6 +65,7 @@ namespace Google.Protobuf
/// </summary>
public static readonly int DefaultBufferSize = 4096;
+ private readonly bool leaveOpen;
private readonly byte[] buffer;
private readonly int limit;
private int position;
@@ -91,20 +92,44 @@ namespace Google.Protobuf
this.buffer = buffer;
this.position = offset;
this.limit = offset + length;
+ leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference
}
- private CodedOutputStream(Stream output, byte[] buffer)
+ private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen)
{
- this.output = output;
+ this.output = ProtoPreconditions.CheckNotNull(output, nameof(output));
this.buffer = buffer;
this.position = 0;
this.limit = buffer.Length;
+ this.leaveOpen = leaveOpen;
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="CodedOutputStream" /> which write to the given stream, and disposes of that
+ /// stream when the returned <c>CodedOutputStream</c> is disposed.
+ /// </summary>
+ /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
+ public CodedOutputStream(Stream output) : this(output, DefaultBufferSize, false)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new CodedOutputStream which write to the given stream and uses
+ /// the specified buffer size.
+ /// </summary>
+ /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param>
+ /// <param name="bufferSize">The size of buffer to use internally.</param>
+ public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize], false)
+ {
}
/// <summary>
/// Creates a new CodedOutputStream which write to the given stream.
/// </summary>
- public CodedOutputStream(Stream output) : this(output, DefaultBufferSize)
+ /// <param name="output">The stream to write to.</param>
+ /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
+ /// if <c>false</c>, the provided stream is disposed as well.</param>
+ public CodedOutputStream(Stream output, bool leaveOpen) : this(output, DefaultBufferSize, leaveOpen)
{
}
@@ -112,9 +137,13 @@ namespace Google.Protobuf
/// Creates a new CodedOutputStream which write to the given stream and uses
/// the specified buffer size.
/// </summary>
- public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize])
+ /// <param name="output">The stream to write to.</param>
+ /// <param name="bufferSize">The size of buffer to use internally.</param>
+ /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed;
+ /// if <c>false</c>, the provided stream is disposed as well.</param>
+ public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen) : this(output, new byte[bufferSize], leaveOpen)
{
- }
+ }
#endregion
/// <summary>
@@ -660,6 +689,30 @@ namespace Google.Protobuf
}
/// <summary>
+ /// Flushes any buffered data and optionally closes the underlying stream, if any.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// By default, any underlying stream is closed by this method. To configure this behaviour,
+ /// use a constructor overload with a <c>leaveOpen</c> parameter. If this instance does not
+ /// have an underlying stream, this method does nothing.
+ /// </para>
+ /// <para>
+ /// For the sake of efficiency, calling this method does not prevent future write calls - but
+ /// if a later write ends up writing to a stream which has been disposed, that is likely to
+ /// fail. It is recommend that you not call any other methods after this.
+ /// </para>
+ /// </remarks>
+ public void Dispose()
+ {
+ Flush();
+ if (!leaveOpen)
+ {
+ output.Dispose();
+ }
+ }
+
+ /// <summary>
/// Flushes any buffered data to the underlying stream (if there is one).
/// </summary>
public void Flush()
@@ -705,4 +758,4 @@ namespace Google.Protobuf
}
}
}
-} \ No newline at end of file
+}
diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs
index c0ed28ae..993a89d7 100644
--- a/csharp/src/Google.Protobuf/Collections/MapField.cs
+++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -34,6 +34,7 @@ using Google.Protobuf.Reflection;
using System;
using System.Collections;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
using Google.Protobuf.Compatibility;
@@ -53,6 +54,13 @@ namespace Google.Protobuf.Collections
/// For string keys, the equality comparison is provided by <see cref="StringComparer.Ordinal" />.
/// </para>
/// <para>
+ /// Null values are not permitted in the map, either for wrapper types or regular messages.
+ /// If a map is deserialized from a data stream and the value is missing from an entry, a default value
+ /// is created instead. For primitive types, that is the regular default value (0, the empty string and so
+ /// on); for message types, an empty instance of the message is created, as if the map entry contained a 0-length
+ /// encoded value for the field.
+ /// </para>
+ /// <para>
/// This implementation does not generally prohibit the use of key/value types which are not
/// supported by Protocol Buffers (e.g. using a key type of <code>byte</code>) but nor does it guarantee
/// that all operations will work in such cases.
@@ -61,35 +69,11 @@ namespace Google.Protobuf.Collections
public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary
{
// TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.)
- private readonly bool allowNullValues;
private readonly Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>> map =
new Dictionary<TKey, LinkedListNode<KeyValuePair<TKey, TValue>>>();
private readonly LinkedList<KeyValuePair<TKey, TValue>> list = new LinkedList<KeyValuePair<TKey, TValue>>();
/// <summary>
- /// Constructs a new map field, defaulting the value nullability to only allow null values for message types
- /// and non-nullable value types.
- /// </summary>
- public MapField() : this(typeof(IMessage).IsAssignableFrom(typeof(TValue)) || Nullable.GetUnderlyingType(typeof(TValue)) != null)
- {
- }
-
- /// <summary>
- /// Constructs a new map field, overriding the choice of whether null values are permitted in the map.
- /// This is used by wrapper types, where maps with string and bytes wrappers as the value types
- /// support null values.
- /// </summary>
- /// <param name="allowNullValues">Whether null values are permitted in the map or not.</param>
- public MapField(bool allowNullValues)
- {
- if (allowNullValues && typeof(TValue).IsValueType() && Nullable.GetUnderlyingType(typeof(TValue)) == null)
- {
- throw new ArgumentException("allowNullValues", "Non-nullable value types do not support null values");
- }
- this.allowNullValues = allowNullValues;
- }
-
- /// <summary>
/// Creates a deep clone of this object.
/// </summary>
/// <returns>
@@ -97,13 +81,13 @@ namespace Google.Protobuf.Collections
/// </returns>
public MapField<TKey, TValue> Clone()
{
- var clone = new MapField<TKey, TValue>(allowNullValues);
+ var clone = new MapField<TKey, TValue>();
// Keys are never cloneable. Values might be.
if (typeof(IDeepCloneable<TValue>).IsAssignableFrom(typeof(TValue)))
{
foreach (var pair in list)
{
- clone.Add(pair.Key, pair.Value == null ? pair.Value : ((IDeepCloneable<TValue>)pair.Value).Clone());
+ clone.Add(pair.Key, ((IDeepCloneable<TValue>)pair.Value).Clone());
}
}
else
@@ -140,7 +124,7 @@ namespace Google.Protobuf.Collections
/// <returns><c>true</c> if the map contains the given key; <c>false</c> otherwise.</returns>
public bool ContainsKey(TKey key)
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
return map.ContainsKey(key);
}
@@ -157,7 +141,7 @@ namespace Google.Protobuf.Collections
/// <returns><c>true</c> if the map contained the given key before the entry was removed; <c>false</c> otherwise.</returns>
public bool Remove(TKey key)
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
LinkedListNode<KeyValuePair<TKey, TValue>> node;
if (map.TryGetValue(key, out node))
{
@@ -205,7 +189,7 @@ namespace Google.Protobuf.Collections
{
get
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
TValue value;
if (TryGetValue(key, out value))
{
@@ -215,11 +199,11 @@ namespace Google.Protobuf.Collections
}
set
{
- Preconditions.CheckNotNullUnconstrained(key, "key");
+ ProtoPreconditions.CheckNotNullUnconstrained(key, "key");
// value == null check here is redundant, but avoids boxing.
- if (value == null && !allowNullValues)
+ if (value == null)
{
- Preconditions.CheckNotNullUnconstrained(value, "value");
+ ProtoPreconditions.CheckNotNullUnconstrained(value, "value");
}
LinkedListNode<KeyValuePair<TKey, TValue>> node;
var pair = new KeyValuePair<TKey, TValue>(key, value);
@@ -246,12 +230,12 @@ namespace Google.Protobuf.Collections
public ICollection<TValue> Values { get { return new MapView<TValue>(this, pair => pair.Value, ContainsValue); } }
/// <summary>
- /// Adds the specified entries to the map.
+ /// Adds the specified entries to the map. The keys and values are not automatically cloned.
/// </summary>
/// <param name="entries">The entries to add to the map.</param>
public void Add(IDictionary<TKey, TValue> entries)
{
- Preconditions.CheckNotNull(entries, "entries");
+ ProtoPreconditions.CheckNotNull(entries, "entries");
foreach (var pair in entries)
{
Add(pair.Key, pair.Value);
@@ -347,11 +331,6 @@ namespace Google.Protobuf.Collections
}
/// <summary>
- /// Returns whether or not this map allows values to be null.
- /// </summary>
- public bool AllowsNullValues { get { return allowNullValues; } }
-
- /// <summary>
/// Gets the number of elements contained in the map.
/// </summary>
public int Count { get { return list.Count; } }
@@ -496,9 +475,9 @@ namespace Google.Protobuf.Collections
/// </summary>
public override string ToString()
{
- var builder = new StringBuilder();
- JsonFormatter.Default.WriteDictionary(builder, this);
- return builder.ToString();
+ var writer = new StringWriter();
+ JsonFormatter.Default.WriteDictionary(writer, this);
+ return writer.ToString();
}
#region IDictionary explicit interface implementation
@@ -523,7 +502,7 @@ namespace Google.Protobuf.Collections
void IDictionary.Remove(object key)
{
- Preconditions.CheckNotNull(key, "key");
+ ProtoPreconditions.CheckNotNull(key, "key");
if (!(key is TKey))
{
return;
@@ -552,7 +531,7 @@ namespace Google.Protobuf.Collections
{
get
{
- Preconditions.CheckNotNull(key, "key");
+ ProtoPreconditions.CheckNotNull(key, "key");
if (!(key is TKey))
{
return null;
@@ -632,6 +611,8 @@ namespace Google.Protobuf.Collections
/// </summary>
internal class MessageAdapter : IMessage
{
+ private static readonly byte[] ZeroLengthMessageStreamData = new byte[] { 0 };
+
private readonly Codec codec;
internal TKey Key { get; set; }
internal TValue Value { get; set; }
@@ -665,6 +646,13 @@ namespace Google.Protobuf.Collections
input.SkipLastField();
}
}
+
+ // Corner case: a map entry with a key but no value, where the value type is a message.
+ // Read it as if we'd seen an input stream with no data (i.e. create a "default" message).
+ if (Value == null)
+ {
+ Value = codec.valueCodec.Read(new CodedInputStream(ZeroLengthMessageStreamData));
+ }
}
public void WriteTo(CodedOutputStream output)
diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
index e3f65afe..d1db856c 100644
--- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
+++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs
@@ -33,8 +33,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.IO;
using System.Text;
-using Google.Protobuf.Compatibility;
namespace Google.Protobuf.Collections
{
@@ -96,8 +96,8 @@ namespace Google.Protobuf.Collections
// iteration.
uint tag = input.LastTag;
var reader = codec.ValueReader;
- // Value types can be packed or not.
- if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited)
+ // Non-nullable value types can be packed or not.
+ if (FieldCodec<T>.IsPackedRepeatedField(tag))
{
int length = input.ReadLength();
if (length > 0)
@@ -134,7 +134,7 @@ namespace Google.Protobuf.Collections
return 0;
}
uint tag = codec.Tag;
- if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited)
+ if (codec.PackedRepeatedField)
{
int dataSize = CalculatePackedDataSize(codec);
return CodedOutputStream.ComputeRawVarint32Size(tag) +
@@ -186,7 +186,7 @@ namespace Google.Protobuf.Collections
}
var writer = codec.ValueWriter;
var tag = codec.Tag;
- if (typeof(T).IsValueType() && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited)
+ if (codec.PackedRepeatedField)
{
// Packed primitive type
uint size = (uint)CalculatePackedDataSize(codec);
@@ -475,9 +475,9 @@ namespace Google.Protobuf.Collections
/// </summary>
public override string ToString()
{
- var builder = new StringBuilder();
- JsonFormatter.Default.WriteList(builder, this);
- return builder.ToString();
+ var writer = new StringWriter();
+ JsonFormatter.Default.WriteList(writer, this);
+ return writer.ToString();
}
/// <summary>
diff --git a/csharp/src/Google.Protobuf/FieldCodec.cs b/csharp/src/Google.Protobuf/FieldCodec.cs
index 20a1f438..98313088 100644
--- a/csharp/src/Google.Protobuf/FieldCodec.cs
+++ b/csharp/src/Google.Protobuf/FieldCodec.cs
@@ -30,6 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using Google.Protobuf.Compatibility;
+using Google.Protobuf.WellKnownTypes;
using System;
using System.Collections.Generic;
@@ -261,20 +263,17 @@ namespace Google.Protobuf
/// </remarks>
private static class WrapperCodecs
{
- // All the field numbers are the same (1).
- private const int WrapperValueFieldNumber = Google.Protobuf.WellKnownTypes.Int32Value.ValueFieldNumber;
-
- private static readonly Dictionary<Type, object> Codecs = new Dictionary<Type, object>
+ private static readonly Dictionary<System.Type, object> Codecs = new Dictionary<System.Type, object>
{
- { typeof(bool), ForBool(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
- { typeof(int), ForInt32(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
- { typeof(long), ForInt64(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
- { typeof(uint), ForUInt32(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
- { typeof(ulong), ForUInt64(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
- { typeof(float), ForFloat(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.Fixed32)) },
- { typeof(double), ForDouble(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.Fixed64)) },
- { typeof(string), ForString(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.LengthDelimited)) },
- { typeof(ByteString), ForBytes(WireFormat.MakeTag(WrapperValueFieldNumber, WireFormat.WireType.LengthDelimited)) }
+ { typeof(bool), ForBool(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
+ { typeof(int), ForInt32(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
+ { typeof(long), ForInt64(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
+ { typeof(uint), ForUInt32(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
+ { typeof(ulong), ForUInt64(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Varint)) },
+ { typeof(float), ForFloat(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Fixed32)) },
+ { typeof(double), ForDouble(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.Fixed64)) },
+ { typeof(string), ForString(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.LengthDelimited)) },
+ { typeof(ByteString), ForBytes(WireFormat.MakeTag(WrappersReflection.WrapperValueFieldNumber, WireFormat.WireType.LengthDelimited)) }
};
/// <summary>
@@ -331,17 +330,24 @@ namespace Google.Protobuf
}
/// <summary>
+ /// <para>
/// An encode/decode pair for a single field. This effectively encapsulates
/// all the information needed to read or write the field value from/to a coded
/// stream.
+ /// </para>
+ /// <para>
+ /// This class is public and has to be as it is used by generated code, but its public
+ /// API is very limited - just what the generated code needs to call directly.
+ /// </para>
/// </summary>
/// <remarks>
- /// This never writes default values to the stream, and is not currently designed
- /// to play well with packed arrays.
+ /// This never writes default values to the stream, and does not address "packedness"
+ /// in repeated fields itself, other than to know whether or not the field *should* be packed.
/// </remarks>
public sealed class FieldCodec<T>
{
private static readonly T DefaultDefault;
+ private static readonly bool TypeSupportsPacking = typeof(T).IsValueType() && Nullable.GetUnderlyingType(typeof(T)) == null;
static FieldCodec()
{
@@ -356,80 +362,31 @@ namespace Google.Protobuf
// Otherwise it's the default value of the CLR type
}
- private static Func<T, bool> CreateDefaultValueCheck<TTmp>(Func<TTmp, bool> check)
- {
- return (Func<T, bool>)(object)check;
- }
-
- private readonly Func<CodedInputStream, T> reader;
- private readonly Action<CodedOutputStream, T> writer;
- private readonly Func<T, int> sizeCalculator;
- private readonly uint tag;
- private readonly int tagSize;
- private readonly int fixedSize;
- // Default value for this codec. Usually the same for every instance of the same type, but
- // for string/ByteString wrapper fields the codec's default value is null, whereas for
- // other string/ByteString fields it's "" or ByteString.Empty.
- private readonly T defaultValue;
+ internal static bool IsPackedRepeatedField(uint tag) =>
+ TypeSupportsPacking && WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited;
- internal FieldCodec(
- Func<CodedInputStream, T> reader,
- Action<CodedOutputStream, T> writer,
- Func<T, int> sizeCalculator,
- uint tag) : this(reader, writer, sizeCalculator, tag, DefaultDefault)
- {
- }
-
- internal FieldCodec(
- Func<CodedInputStream, T> reader,
- Action<CodedOutputStream, T> writer,
- Func<T, int> sizeCalculator,
- uint tag,
- T defaultValue)
- {
- this.reader = reader;
- this.writer = writer;
- this.sizeCalculator = sizeCalculator;
- this.fixedSize = 0;
- this.tag = tag;
- this.defaultValue = defaultValue;
- tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
- }
-
- internal FieldCodec(
- Func<CodedInputStream, T> reader,
- Action<CodedOutputStream, T> writer,
- int fixedSize,
- uint tag)
- {
- this.reader = reader;
- this.writer = writer;
- this.sizeCalculator = _ => fixedSize;
- this.fixedSize = fixedSize;
- this.tag = tag;
- tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
- }
+ internal bool PackedRepeatedField { get; }
/// <summary>
- /// Returns the size calculator for just a value.
+ /// Returns a delegate to write a value (unconditionally) to a coded output stream.
/// </summary>
- internal Func<T, int> ValueSizeCalculator { get { return sizeCalculator; } }
+ internal Action<CodedOutputStream, T> ValueWriter { get; }
/// <summary>
- /// Returns a delegate to write a value (unconditionally) to a coded output stream.
+ /// Returns the size calculator for just a value.
/// </summary>
- internal Action<CodedOutputStream, T> ValueWriter { get { return writer; } }
+ internal Func<T, int> ValueSizeCalculator { get; }
/// <summary>
/// Returns a delegate to read a value from a coded input stream. It is assumed that
/// the stream is already positioned on the appropriate tag.
/// </summary>
- internal Func<CodedInputStream, T> ValueReader { get { return reader; } }
+ internal Func<CodedInputStream, T> ValueReader { get; }
/// <summary>
/// Returns the fixed size for an entry, or 0 if sizes vary.
/// </summary>
- internal int FixedSize { get { return fixedSize; } }
+ internal int FixedSize { get; }
/// <summary>
/// Gets the tag of the codec.
@@ -437,15 +394,54 @@ namespace Google.Protobuf
/// <value>
/// The tag of the codec.
/// </value>
- public uint Tag { get { return tag; } }
+ internal uint Tag { get; }
/// <summary>
- /// Gets the default value of the codec's type.
+ /// Default value for this codec. Usually the same for every instance of the same type, but
+ /// for string/ByteString wrapper fields the codec's default value is null, whereas for
+ /// other string/ByteString fields it's "" or ByteString.Empty.
/// </summary>
/// <value>
/// The default value of the codec's type.
/// </value>
- public T DefaultValue { get { return defaultValue; } }
+ internal T DefaultValue { get; }
+
+ private readonly int tagSize;
+
+ internal FieldCodec(
+ Func<CodedInputStream, T> reader,
+ Action<CodedOutputStream, T> writer,
+ int fixedSize,
+ uint tag) : this(reader, writer, _ => fixedSize, tag)
+ {
+ FixedSize = fixedSize;
+ }
+
+ internal FieldCodec(
+ Func<CodedInputStream, T> reader,
+ Action<CodedOutputStream, T> writer,
+ Func<T, int> sizeCalculator,
+ uint tag) : this(reader, writer, sizeCalculator, tag, DefaultDefault)
+ {
+ }
+
+ internal FieldCodec(
+ Func<CodedInputStream, T> reader,
+ Action<CodedOutputStream, T> writer,
+ Func<T, int> sizeCalculator,
+ uint tag,
+ T defaultValue)
+ {
+ ValueReader = reader;
+ ValueWriter = writer;
+ ValueSizeCalculator = sizeCalculator;
+ FixedSize = 0;
+ Tag = tag;
+ DefaultValue = defaultValue;
+ tagSize = CodedOutputStream.ComputeRawVarint32Size(tag);
+ // Detect packed-ness once, so we can check for it within RepeatedField<T>.
+ PackedRepeatedField = IsPackedRepeatedField(tag);
+ }
/// <summary>
/// Write a tag and the given value, *if* the value is not the default.
@@ -454,8 +450,8 @@ namespace Google.Protobuf
{
if (!IsDefault(value))
{
- output.WriteTag(tag);
- writer(output, value);
+ output.WriteTag(Tag);
+ ValueWriter(output, value);
}
}
@@ -464,23 +460,14 @@ namespace Google.Protobuf
/// </summary>
/// <param name="input">The input stream to read from.</param>
/// <returns>The value read from the stream.</returns>
- public T Read(CodedInputStream input)
- {
- return reader(input);
- }
+ public T Read(CodedInputStream input) => ValueReader(input);
/// <summary>
/// Calculates the size required to write the given value, with a tag,
/// if the value is not the default.
/// </summary>
- public int CalculateSizeWithTag(T value)
- {
- return IsDefault(value) ? 0 : sizeCalculator(value) + tagSize;
- }
+ public int CalculateSizeWithTag(T value) => IsDefault(value) ? 0 : ValueSizeCalculator(value) + tagSize;
- private bool IsDefault(T value)
- {
- return EqualityComparer<T>.Default.Equals(value, defaultValue);
- }
+ private bool IsDefault(T value) => EqualityComparer<T>.Default.Equals(value, DefaultValue);
}
}
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
index 8c680d46..5557612a 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.csproj
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.csproj
@@ -16,6 +16,8 @@
<FileAlignment>512</FileAlignment>
<OldToolsVersion>3.5</OldToolsVersion>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -62,7 +64,7 @@
<NoStdLib>true</NoStdLib>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<SignAssembly>True</SignAssembly>
- <AssemblyOriginatorKeyFile>C:\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
+ <AssemblyOriginatorKeyFile>..\..\keys\Google.Protobuf.snk</AssemblyOriginatorKeyFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
@@ -83,17 +85,22 @@
<Compile Include="Compatibility\TypeExtensions.cs" />
<Compile Include="FieldCodec.cs" />
<Compile Include="FrameworkPortability.cs" />
+ <Compile Include="ICustomDiagnosticMessage.cs" />
<Compile Include="IDeepCloneable.cs" />
+ <Compile Include="InvalidJsonException.cs" />
<Compile Include="JsonFormatter.cs" />
+ <Compile Include="JsonParser.cs" />
+ <Compile Include="JsonToken.cs" />
+ <Compile Include="JsonTokenizer.cs" />
<Compile Include="MessageExtensions.cs" />
<Compile Include="IMessage.cs" />
<Compile Include="InvalidProtocolBufferException.cs" />
<Compile Include="LimitedInputStream.cs" />
<Compile Include="MessageParser.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Reflection\Descriptor.cs" />
<Compile Include="Reflection\DescriptorBase.cs" />
<Compile Include="Reflection\DescriptorPool.cs" />
- <Compile Include="Reflection\DescriptorProtoFile.cs" />
<Compile Include="Reflection\DescriptorUtil.cs" />
<Compile Include="Reflection\DescriptorValidationException.cs" />
<Compile Include="Reflection\EnumDescriptor.cs" />
@@ -102,7 +109,7 @@
<Compile Include="Reflection\FieldDescriptor.cs" />
<Compile Include="Reflection\FieldType.cs" />
<Compile Include="Reflection\FileDescriptor.cs" />
- <Compile Include="Reflection\GeneratedCodeInfo.cs" />
+ <Compile Include="Reflection\GeneratedClrTypeInfo.cs" />
<Compile Include="Reflection\IDescriptor.cs" />
<Compile Include="Reflection\IFieldAccessor.cs" />
<Compile Include="Reflection\MapFieldAccessor.cs" />
@@ -110,13 +117,15 @@
<Compile Include="Reflection\MethodDescriptor.cs" />
<Compile Include="Reflection\OneofAccessor.cs" />
<Compile Include="Reflection\OneofDescriptor.cs" />
+ <Compile Include="Reflection\OriginalNameAttribute.cs" />
<Compile Include="Reflection\PackageDescriptor.cs" />
<Compile Include="Reflection\PartialClasses.cs" />
<Compile Include="Reflection\ReflectionUtil.cs" />
<Compile Include="Reflection\RepeatedFieldAccessor.cs" />
<Compile Include="Reflection\ServiceDescriptor.cs" />
<Compile Include="Reflection\SingleFieldAccessor.cs" />
- <Compile Include="Preconditions.cs" />
+ <Compile Include="ProtoPreconditions.cs" />
+ <Compile Include="Reflection\TypeRegistry.cs" />
<Compile Include="WellKnownTypes\Any.cs" />
<Compile Include="WellKnownTypes\AnyPartial.cs" />
<Compile Include="WellKnownTypes\Api.cs" />
@@ -124,20 +133,31 @@
<Compile Include="WellKnownTypes\DurationPartial.cs" />
<Compile Include="WellKnownTypes\Empty.cs" />
<Compile Include="WellKnownTypes\FieldMask.cs" />
+ <Compile Include="WellKnownTypes\FieldMaskPartial.cs" />
<Compile Include="WellKnownTypes\SourceContext.cs" />
<Compile Include="WellKnownTypes\Struct.cs" />
<Compile Include="WellKnownTypes\TimeExtensions.cs" />
<Compile Include="WellKnownTypes\Timestamp.cs" />
<Compile Include="WellKnownTypes\TimestampPartial.cs" />
<Compile Include="WellKnownTypes\Type.cs" />
+ <Compile Include="WellKnownTypes\ValuePartial.cs" />
<Compile Include="WellKnownTypes\Wrappers.cs" />
+ <Compile Include="WellKnownTypes\WrappersPartial.cs" />
<Compile Include="WireFormat.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Google.Protobuf.nuspec" />
+ <None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+ <Import Project="..\packages\NuSpec.ReferenceGenerator.1.4.1\build\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\NuSpec.ReferenceGenerator.targets" Condition="Exists('..\packages\NuSpec.ReferenceGenerator.1.4.1\build\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\NuSpec.ReferenceGenerator.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\NuSpec.ReferenceGenerator.1.4.1\build\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\NuSpec.ReferenceGenerator.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NuSpec.ReferenceGenerator.1.4.1\build\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\NuSpec.ReferenceGenerator.targets'))" />
+ </Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
diff --git a/csharp/src/Google.Protobuf/Google.Protobuf.nuspec b/csharp/src/Google.Protobuf/Google.Protobuf.nuspec
index 9542138a..90e3da3d 100644
--- a/csharp/src/Google.Protobuf/Google.Protobuf.nuspec
+++ b/csharp/src/Google.Protobuf/Google.Protobuf.nuspec
@@ -1,11 +1,11 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<package>
<metadata>
<id>Google.Protobuf</id>
<title>Google Protocol Buffers C#</title>
<summary>C# runtime library for Protocol Buffers - Google's data interchange format.</summary>
<description>See project site for more info.</description>
- <version>3.0.0-alpha4</version>
+ <version>3.0.0-beta3</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/google/protobuf/blob/master/LICENSE</licenseUrl>
@@ -14,24 +14,41 @@
<releaseNotes>C# proto3 support</releaseNotes>
<copyright>Copyright 2015, Google Inc.</copyright>
<tags>Protocol Buffers Binary Serialization Format Google proto proto3</tags>
+ <dependencies>
+ <!-- Dependencies for older, monolithic-assembly platforms -->
+ <group targetFramework="net45" />
+ <group targetFramework="wp8" />
+ <group targetFramework="win8" />
+ <group targetFramework="wpa81" />
+ <group targetFramework="xamarin.ios" />
+ <group targetFramework="monotouch" />
+ <group targetFramework="monoandroid" />
+ <!-- Dependencies for newer, more granular platforms (.NET Core etc) -->
+ <group targetFramework="dotnet">
+ <dependency id="System.Collections" version="4.0.0" />
+ <dependency id="System.Diagnostics.Debug" version="4.0.0" />
+ <dependency id="System.Globalization" version="4.0.0" />
+ <dependency id="System.IO" version="4.0.0" />
+ <dependency id="System.Linq" version="4.0.0" />
+ <dependency id="System.Linq.Expressions" version="4.0.0" />
+ <dependency id="System.ObjectModel" version="4.0.0" />
+ <dependency id="System.Reflection" version="4.0.0" />
+ <dependency id="System.Reflection.Extensions" version="4.0.0" />
+ <dependency id="System.Runtime" version="4.0.0" />
+ <dependency id="System.Runtime.Extensions" version="4.0.0" />
+ <dependency id="System.Text.Encoding" version="4.0.0" />
+ <dependency id="System.Text.RegularExpressions" version="4.0.0" />
+ <dependency id="System.Threading" version="4.0.0" />
+ </group>
+ </dependencies>
</metadata>
<files>
<file src="bin/ReleaseSigned/Google.Protobuf.dll" target="lib/portable-net45+netcore45+wpa81+wp8" />
- <file src="bin/ReleaseSigned/Google.Protobuf.pdb" target="lib/portable-net45+netcore45+wpa81+wp8" />
- <file src="bin/ReleaseSigned/Google.Protobuf.xml" target="lib/portable-net45+netcore45+wpa81+wp8" />
- <file src="**\*.cs" target="src" />
- <file src="..\..\..\cmake\Release\protoc.exe" target="tools" />
- <file src="..\..\..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\api.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\descriptor.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\duration.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\empty.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\field_mask.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\source_context.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\struct.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\timestamp.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\any.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\type.proto" target="tools\google\protobuf" />
- <file src="..\..\..\src\google\protobuf\wrappers.proto" target="tools\google\protobuf" />
+ <file src="bin/ReleaseSigned/Google.Protobuf.pdb" target="lib/portable-net45+netcore45+wpa81+wp8" />
+ <file src="bin/ReleaseSigned/Google.Protobuf.xml" target="lib/portable-net45+netcore45+wpa81+wp8" />
+ <file src="bin/ReleaseSigned/Google.Protobuf.dll" target="lib/dotnet" />
+ <file src="bin/ReleaseSigned/Google.Protobuf.pdb" target="lib/dotnet" />
+ <file src="bin/ReleaseSigned/Google.Protobuf.xml" target="lib/dotnet" />
+ <file src="**\*.cs" target="src" />
</files>
</package>
diff --git a/csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs b/csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs
new file mode 100644
index 00000000..a0090569
--- /dev/null
+++ b/csharp/src/Google.Protobuf/ICustomDiagnosticMessage.cs
@@ -0,0 +1,69 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+#endregion
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// A message type that has a custom string format for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Calling <see cref="object.ToString"/> on a generated message type normally
+ /// returns the JSON representation. If a message type implements this interface,
+ /// then the <see cref="ToDiagnosticString"/> method will be called instead of the regular
+ /// JSON formatting code, but only when <c>ToString()</c> is called either on the message itself
+ /// or on another message which contains it. This does not affect the normal JSON formatting of
+ /// the message.
+ /// </para>
+ /// <para>
+ /// For example, if you create a proto message representing a GUID, the internal
+ /// representation may be a <c>bytes</c> field or four <c>fixed32</c> fields. However, when debugging
+ /// it may be more convenient to see a result in the same format as <see cref="System.Guid"/> provides.
+ /// </para>
+ /// <para>This interface extends <see cref="IMessage"/> to avoid it accidentally being implemented
+ /// on types other than messages, where it would not be used by anything in the framework.</para>
+ /// </remarks>
+ public interface ICustomDiagnosticMessage : IMessage
+ {
+ /// <summary>
+ /// Returns a string representation of this object, for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// This method is called when a message is formatted as part of a <see cref="object.ToString"/>
+ /// call. It does not affect the JSON representation used by <see cref="JsonFormatter"/> other than
+ /// in calls to <see cref="JsonFormatter.ToDiagnosticString(IMessage)"/>. While it is recommended
+ /// that the result is valid JSON, this is never assumed by the Protobuf library.
+ /// </remarks>
+ /// <returns>A string representation of this object, for diagnostic purposes.</returns>
+ string ToDiagnosticString();
+ }
+}
diff --git a/csharp/src/Google.Protobuf/InvalidJsonException.cs b/csharp/src/Google.Protobuf/InvalidJsonException.cs
new file mode 100644
index 00000000..b5434201
--- /dev/null
+++ b/csharp/src/Google.Protobuf/InvalidJsonException.cs
@@ -0,0 +1,53 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 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.
+#endregion
+
+using System.IO;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Thrown when an attempt is made to parse invalid JSON, e.g. using
+ /// a non-string property key, or including a redundant comma. Parsing a protocol buffer
+ /// message represented in JSON using <see cref="JsonParser"/> can throw both this
+ /// exception and <see cref="InvalidProtocolBufferException"/> depending on the situation. This
+ /// exception is only thrown for "pure JSON" errors, whereas <c>InvalidProtocolBufferException</c>
+ /// is thrown when the JSON may be valid in and of itself, but cannot be parsed as a protocol buffer
+ /// message.
+ /// </summary>
+ public sealed class InvalidJsonException : IOException
+ {
+ internal InvalidJsonException(string message)
+ : base(message)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs b/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
index 01d55395..eeb0f13a 100644
--- a/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
+++ b/csharp/src/Google.Protobuf/InvalidProtocolBufferException.cs
@@ -30,6 +30,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using System;
using System.IO;
namespace Google.Protobuf
@@ -45,6 +46,11 @@ namespace Google.Protobuf
{
}
+ internal InvalidProtocolBufferException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
internal static InvalidProtocolBufferException MoreDataAvailable()
{
return new InvalidProtocolBufferException(
@@ -82,6 +88,11 @@ namespace Google.Protobuf
"Protocol message contained an invalid tag (zero).");
}
+ internal static InvalidProtocolBufferException InvalidBase64(Exception innerException)
+ {
+ return new InvalidProtocolBufferException("Invalid base64 data", innerException);
+ }
+
internal static InvalidProtocolBufferException InvalidEndTag()
{
return new InvalidProtocolBufferException(
@@ -95,6 +106,13 @@ namespace Google.Protobuf
"Use CodedInputStream.SetRecursionLimit() to increase the depth limit.");
}
+ internal static InvalidProtocolBufferException JsonRecursionLimitExceeded()
+ {
+ return new InvalidProtocolBufferException(
+ "Protocol message had too many levels of nesting. May be malicious. " +
+ "Use JsonParser.Settings to increase the depth limit.");
+ }
+
internal static InvalidProtocolBufferException SizeLimitExceeded()
{
return new InvalidProtocolBufferException(
diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs
index 3f9bd478..83772473 100644
--- a/csharp/src/Google.Protobuf/JsonFormatter.cs
+++ b/csharp/src/Google.Protobuf/JsonFormatter.cs
@@ -36,7 +36,10 @@ using System.Globalization;
using System.Text;
using Google.Protobuf.Reflection;
using Google.Protobuf.WellKnownTypes;
+using System.IO;
using System.Linq;
+using System.Collections.Generic;
+using System.Reflection;
namespace Google.Protobuf
{
@@ -55,12 +58,20 @@ namespace Google.Protobuf
/// </remarks>
public sealed class JsonFormatter
{
- private static JsonFormatter defaultInstance = new JsonFormatter(Settings.Default);
+ internal const string AnyTypeUrlField = "@type";
+ internal const string AnyDiagnosticValueField = "@value";
+ internal const string AnyWellKnownTypeValueField = "value";
+ private const string TypeUrlPrefix = "type.googleapis.com";
+ private const string NameValueSeparator = ": ";
+ private const string PropertySeparator = ", ";
/// <summary>
/// Returns a formatter using the default settings.
/// </summary>
- public static JsonFormatter Default { get { return defaultInstance; } }
+ public static JsonFormatter Default { get; } = new JsonFormatter(Settings.Default);
+
+ // A JSON formatter which *only* exists
+ private static readonly JsonFormatter diagnosticFormatter = new JsonFormatter(Settings.Default);
/// <summary>
/// The JSON representation of the first 160 characters of Unicode.
@@ -114,6 +125,8 @@ namespace Google.Protobuf
private readonly Settings settings;
+ private bool DiagnosticOnly => ReferenceEquals(this, diagnosticFormatter);
+
/// <summary>
/// Creates a new formatted with the given settings.
/// </summary>
@@ -130,34 +143,84 @@ namespace Google.Protobuf
/// <returns>The formatted message.</returns>
public string Format(IMessage message)
{
- Preconditions.CheckNotNull(message, "message");
- StringBuilder builder = new StringBuilder();
+ var writer = new StringWriter();
+ Format(message, writer);
+ return writer.ToString();
+ }
+
+ /// <summary>
+ /// Formats the specified message as JSON.
+ /// </summary>
+ /// <param name="message">The message to format.</param>
+ /// <param name="writer">The TextWriter to write the formatted message to.</param>
+ /// <returns>The formatted message.</returns>
+ public void Format(IMessage message, TextWriter writer)
+ {
+ ProtoPreconditions.CheckNotNull(message, nameof(message));
+ ProtoPreconditions.CheckNotNull(writer, nameof(writer));
+
if (message.Descriptor.IsWellKnownType)
{
- WriteWellKnownTypeValue(builder, message.Descriptor, message, false);
+ WriteWellKnownTypeValue(writer, message.Descriptor, message);
}
else
{
- WriteMessage(builder, message);
+ WriteMessage(writer, message);
}
- return builder.ToString();
}
- private void WriteMessage(StringBuilder builder, IMessage message)
+ /// <summary>
+ /// Converts a message to JSON for diagnostic purposes with no extra context.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This differs from calling <see cref="Format(IMessage)"/> on the default JSON
+ /// formatter in its handling of <see cref="Any"/>. As no type registry is available
+ /// in <see cref="object.ToString"/> calls, the normal way of resolving the type of
+ /// an <c>Any</c> message cannot be applied. Instead, a JSON property named <c>@value</c>
+ /// is included with the base64 data from the <see cref="Any.Value"/> property of the message.
+ /// </para>
+ /// <para>The value returned by this method is only designed to be used for diagnostic
+ /// purposes. It may not be parsable by <see cref="JsonParser"/>, and may not be parsable
+ /// by other Protocol Buffer implementations.</para>
+ /// </remarks>
+ /// <param name="message">The message to format for diagnostic purposes.</param>
+ /// <returns>The diagnostic-only JSON representation of the message</returns>
+ public static string ToDiagnosticString(IMessage message)
+ {
+ ProtoPreconditions.CheckNotNull(message, nameof(message));
+ return diagnosticFormatter.Format(message);
+ }
+
+ private void WriteMessage(TextWriter writer, IMessage message)
{
if (message == null)
{
- WriteNull(builder);
+ WriteNull(writer);
return;
}
- builder.Append("{ ");
+ if (DiagnosticOnly)
+ {
+ ICustomDiagnosticMessage customDiagnosticMessage = message as ICustomDiagnosticMessage;
+ if (customDiagnosticMessage != null)
+ {
+ writer.Write(customDiagnosticMessage.ToDiagnosticString());
+ return;
+ }
+ }
+ writer.Write("{ ");
+ bool writtenFields = WriteMessageFields(writer, message, false);
+ writer.Write(writtenFields ? " }" : "}");
+ }
+
+ private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten)
+ {
var fields = message.Descriptor.Fields;
- bool first = true;
+ bool first = !assumeFirstFieldWritten;
// First non-oneof fields
foreach (var field in fields.InFieldNumberOrder())
{
var accessor = field.Accessor;
- // Oneofs are written later
if (field.ContainingOneof != null && field.ContainingOneof.Accessor.GetCaseFieldDescriptor(message) != field)
{
continue;
@@ -169,26 +232,49 @@ namespace Google.Protobuf
{
continue;
}
- // Omit awkward (single) values such as unknown enum values
- if (!field.IsRepeated && !field.IsMap && !CanWriteSingleValue(value))
- {
- continue;
- }
// Okay, all tests complete: let's write the field value...
if (!first)
{
- builder.Append(", ");
+ writer.Write(PropertySeparator);
}
- WriteString(builder, ToCamelCase(accessor.Descriptor.Name));
- builder.Append(": ");
- WriteValue(builder, value);
+
+ WriteString(writer, accessor.Descriptor.JsonName);
+ writer.Write(NameValueSeparator);
+ WriteValue(writer, value);
+
first = false;
- }
- builder.Append(first ? "}" : " }");
+ }
+ return !first;
+ }
+
+ /// <summary>
+ /// Camel-case converter with added strictness for field mask formatting.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception>
+ private static string ToCamelCaseForFieldMask(string input)
+ {
+ for (int i = 0; i < input.Length; i++)
+ {
+ char c = input[i];
+ if (c >= 'A' && c <= 'Z')
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
+ }
+ if (c == '_' && i < input.Length - 1)
+ {
+ char next = input[i + 1];
+ if (next < 'a' || next > 'z')
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {input}");
+ }
+ }
+ }
+ return ToCamelCase(input);
}
// Converted from src/google/protobuf/util/internal/utility.cc ToCamelCase
+ // TODO: Use the new field in FieldDescriptor.
internal static string ToCamelCase(string input)
{
bool capitalizeNext = false;
@@ -240,9 +326,9 @@ namespace Google.Protobuf
return result.ToString();
}
- private static void WriteNull(StringBuilder builder)
+ private static void WriteNull(TextWriter writer)
{
- builder.Append("null");
+ writer.Write("null");
}
private static bool IsDefaultValue(IFieldAccessor accessor, object value)
@@ -292,63 +378,71 @@ namespace Google.Protobuf
}
}
- private void WriteValue(StringBuilder builder, object value)
+ private void WriteValue(TextWriter writer, object value)
{
if (value == null)
{
- WriteNull(builder);
+ WriteNull(writer);
}
else if (value is bool)
{
- builder.Append((bool) value ? "true" : "false");
+ writer.Write((bool)value ? "true" : "false");
}
else if (value is ByteString)
{
// Nothing in Base64 needs escaping
- builder.Append('"');
- builder.Append(((ByteString) value).ToBase64());
- builder.Append('"');
+ writer.Write('"');
+ writer.Write(((ByteString)value).ToBase64());
+ writer.Write('"');
}
else if (value is string)
{
- WriteString(builder, (string) value);
+ WriteString(writer, (string)value);
}
else if (value is IDictionary)
{
- WriteDictionary(builder, (IDictionary) value);
+ WriteDictionary(writer, (IDictionary)value);
}
else if (value is IList)
{
- WriteList(builder, (IList) value);
+ WriteList(writer, (IList)value);
}
else if (value is int || value is uint)
{
IFormattable formattable = (IFormattable) value;
- builder.Append(formattable.ToString("d", CultureInfo.InvariantCulture));
+ writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture));
}
else if (value is long || value is ulong)
{
- builder.Append('"');
+ writer.Write('"');
IFormattable formattable = (IFormattable) value;
- builder.Append(formattable.ToString("d", CultureInfo.InvariantCulture));
- builder.Append('"');
+ writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture));
+ writer.Write('"');
}
else if (value is System.Enum)
{
- WriteString(builder, value.ToString());
+ string name = OriginalEnumValueHelper.GetOriginalName(value);
+ if (name != null)
+ {
+ WriteString(writer, name);
+ }
+ else
+ {
+ WriteValue(writer, (int)value);
+ }
}
else if (value is float || value is double)
{
string text = ((IFormattable) value).ToString("r", CultureInfo.InvariantCulture);
if (text == "NaN" || text == "Infinity" || text == "-Infinity")
{
- builder.Append('"');
- builder.Append(text);
- builder.Append('"');
+ writer.Write('"');
+ writer.Write(text);
+ writer.Write('"');
}
else
{
- builder.Append(text);
+ writer.Write(text);
}
}
else if (value is IMessage)
@@ -356,11 +450,11 @@ namespace Google.Protobuf
IMessage message = (IMessage) value;
if (message.Descriptor.IsWellKnownType)
{
- WriteWellKnownTypeValue(builder, message.Descriptor, value, true);
+ WriteWellKnownTypeValue(writer, message.Descriptor, value);
}
else
{
- WriteMessage(builder, (IMessage) value);
+ WriteMessage(writer, (IMessage)value);
}
}
else
@@ -375,73 +469,70 @@ namespace Google.Protobuf
/// values are using the embedded well-known types, in order to allow for dynamic messages
/// in the future.
/// </summary>
- private void WriteWellKnownTypeValue(StringBuilder builder, MessageDescriptor descriptor, object value, bool inField)
+ private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value)
{
+ // Currently, we can never actually get here, because null values are always handled by the caller. But if we *could*,
+ // this would do the right thing.
if (value == null)
{
- WriteNull(builder);
+ WriteNull(writer);
return;
}
- // For wrapper types, the value will be the (possibly boxed) "native" value,
- // so we can write it as if we were unconditionally writing the Value field for the wrapper type.
- if (descriptor.File == Int32Value.Descriptor.File)
+ // For wrapper types, the value will either be the (possibly boxed) "native" value,
+ // or the message itself if we're formatting it at the top level (e.g. just calling ToString on the object itself).
+ // If it's the message form, we can extract the value first, which *will* be the (possibly boxed) native value,
+ // and then proceed, writing it as if we were definitely in a field. (We never need to wrap it in an extra string...
+ // WriteValue will do the right thing.)
+ if (descriptor.IsWrapperType)
{
- WriteValue(builder, value);
+ if (value is IMessage)
+ {
+ var message = (IMessage) value;
+ value = message.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber].Accessor.GetValue(message);
+ }
+ WriteValue(writer, value);
return;
}
if (descriptor.FullName == Timestamp.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteTimestamp, inField);
+ WriteTimestamp(writer, (IMessage)value);
return;
}
if (descriptor.FullName == Duration.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteDuration, inField);
+ WriteDuration(writer, (IMessage)value);
return;
}
if (descriptor.FullName == FieldMask.Descriptor.FullName)
{
- MaybeWrapInString(builder, value, WriteFieldMask, inField);
+ WriteFieldMask(writer, (IMessage)value);
return;
}
if (descriptor.FullName == Struct.Descriptor.FullName)
{
- WriteStruct(builder, (IMessage) value);
+ WriteStruct(writer, (IMessage)value);
return;
}
if (descriptor.FullName == ListValue.Descriptor.FullName)
{
var fieldAccessor = descriptor.Fields[ListValue.ValuesFieldNumber].Accessor;
- WriteList(builder, (IList) fieldAccessor.GetValue((IMessage) value));
+ WriteList(writer, (IList)fieldAccessor.GetValue((IMessage)value));
return;
}
if (descriptor.FullName == Value.Descriptor.FullName)
{
- WriteStructFieldValue(builder, (IMessage) value);
+ WriteStructFieldValue(writer, (IMessage)value);
return;
}
- WriteMessage(builder, (IMessage) value);
- }
-
- /// <summary>
- /// Some well-known types end up as string values... so they need wrapping in quotes, but only
- /// when they're being used as fields within another message.
- /// </summary>
- private void MaybeWrapInString(StringBuilder builder, object value, Action<StringBuilder, IMessage> action, bool inField)
- {
- if (inField)
+ if (descriptor.FullName == Any.Descriptor.FullName)
{
- builder.Append('"');
- action(builder, (IMessage) value);
- builder.Append('"');
- }
- else
- {
- action(builder, (IMessage) value);
+ WriteAny(writer, (IMessage)value);
+ return;
}
+ WriteMessage(writer, (IMessage)value);
}
- private void WriteTimestamp(StringBuilder builder, IMessage value)
+ private void WriteTimestamp(TextWriter writer, IMessage value)
{
// TODO: In the common case where this *is* using the built-in Timestamp type, we could
// avoid all the reflection at this point, by casting to Timestamp. In the interests of
@@ -449,72 +540,79 @@ namespace Google.Protobuf
// it still works in that case.
int nanos = (int) value.Descriptor.Fields[Timestamp.NanosFieldNumber].Accessor.GetValue(value);
long seconds = (long) value.Descriptor.Fields[Timestamp.SecondsFieldNumber].Accessor.GetValue(value);
-
- // Even if the original message isn't using the built-in classes, we can still build one... and then
- // rely on it being normalized.
- Timestamp normalized = Timestamp.Normalize(seconds, nanos);
- // Use .NET's formatting for the value down to the second, including an opening double quote (as it's a string value)
- DateTime dateTime = normalized.ToDateTime();
- builder.Append(dateTime.ToString("yyyy'-'MM'-'dd'T'HH:mm:ss", CultureInfo.InvariantCulture));
- AppendNanoseconds(builder, Math.Abs(normalized.Nanos));
- builder.Append('Z');
+ writer.Write(Timestamp.ToJson(seconds, nanos, DiagnosticOnly));
}
- private void WriteDuration(StringBuilder builder, IMessage value)
+ private void WriteDuration(TextWriter writer, IMessage value)
{
// TODO: Same as for WriteTimestamp
int nanos = (int) value.Descriptor.Fields[Duration.NanosFieldNumber].Accessor.GetValue(value);
long seconds = (long) value.Descriptor.Fields[Duration.SecondsFieldNumber].Accessor.GetValue(value);
-
- // Even if the original message isn't using the built-in classes, we can still build one... and then
- // rely on it being normalized.
- Duration normalized = Duration.Normalize(seconds, nanos);
-
- // The seconds part will normally provide the minus sign if we need it, but not if it's 0...
- if (normalized.Seconds == 0 && normalized.Nanos < 0)
- {
- builder.Append('-');
- }
-
- builder.Append(normalized.Seconds.ToString("d", CultureInfo.InvariantCulture));
- AppendNanoseconds(builder, Math.Abs(normalized.Nanos));
- builder.Append('s');
+ writer.Write(Duration.ToJson(seconds, nanos, DiagnosticOnly));
}
- private void WriteFieldMask(StringBuilder builder, IMessage value)
+ private void WriteFieldMask(TextWriter writer, IMessage value)
{
- IList paths = (IList) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
- AppendEscapedString(builder, string.Join(",", paths.Cast<string>().Select(ToCamelCase)));
+ var paths = (IList<string>) value.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(value);
+ writer.Write(FieldMask.ToJson(paths, DiagnosticOnly));
}
- /// <summary>
- /// Appends a number of nanoseconds to a StringBuilder. Either 0 digits are added (in which
- /// case no "." is appended), or 3 6 or 9 digits.
- /// </summary>
- private static void AppendNanoseconds(StringBuilder builder, int nanos)
+ private void WriteAny(TextWriter writer, IMessage value)
{
- if (nanos != 0)
+ if (DiagnosticOnly)
{
- builder.Append('.');
- // Output to 3, 6 or 9 digits.
- if (nanos % 1000000 == 0)
- {
- builder.Append((nanos / 1000000).ToString("d", CultureInfo.InvariantCulture));
- }
- else if (nanos % 1000 == 0)
- {
- builder.Append((nanos / 1000).ToString("d", CultureInfo.InvariantCulture));
- }
- else
- {
- builder.Append(nanos.ToString("d", CultureInfo.InvariantCulture));
- }
+ WriteDiagnosticOnlyAny(writer, value);
+ return;
}
+
+ string typeUrl = (string) value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
+ ByteString data = (ByteString) value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
+ string typeName = Any.GetTypeName(typeUrl);
+ MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
+ if (descriptor == null)
+ {
+ throw new InvalidOperationException($"Type registry has no descriptor for type name '{typeName}'");
+ }
+ IMessage message = descriptor.Parser.ParseFrom(data);
+ writer.Write("{ ");
+ WriteString(writer, AnyTypeUrlField);
+ writer.Write(NameValueSeparator);
+ WriteString(writer, typeUrl);
+
+ if (descriptor.IsWellKnownType)
+ {
+ writer.Write(PropertySeparator);
+ WriteString(writer, AnyWellKnownTypeValueField);
+ writer.Write(NameValueSeparator);
+ WriteWellKnownTypeValue(writer, descriptor, message);
+ }
+ else
+ {
+ WriteMessageFields(writer, message, true);
+ }
+ writer.Write(" }");
}
- private void WriteStruct(StringBuilder builder, IMessage message)
+ private void WriteDiagnosticOnlyAny(TextWriter writer, IMessage value)
{
- builder.Append("{ ");
+ string typeUrl = (string) value.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.GetValue(value);
+ ByteString data = (ByteString) value.Descriptor.Fields[Any.ValueFieldNumber].Accessor.GetValue(value);
+ writer.Write("{ ");
+ WriteString(writer, AnyTypeUrlField);
+ writer.Write(NameValueSeparator);
+ WriteString(writer, typeUrl);
+ writer.Write(PropertySeparator);
+ WriteString(writer, AnyDiagnosticValueField);
+ writer.Write(NameValueSeparator);
+ writer.Write('"');
+ writer.Write(data.ToBase64());
+ writer.Write('"');
+ writer.Write(" }");
+ }
+
+ private void WriteStruct(TextWriter writer, IMessage message)
+ {
+ writer.Write("{ ");
IDictionary fields = (IDictionary) message.Descriptor.Fields[Struct.FieldsFieldNumber].Accessor.GetValue(message);
bool first = true;
foreach (DictionaryEntry entry in fields)
@@ -528,17 +626,17 @@ namespace Google.Protobuf
if (!first)
{
- builder.Append(", ");
+ writer.Write(PropertySeparator);
}
- WriteString(builder, key);
- builder.Append(": ");
- WriteStructFieldValue(builder, value);
+ WriteString(writer, key);
+ writer.Write(NameValueSeparator);
+ WriteStructFieldValue(writer, value);
first = false;
}
- builder.Append(first ? "}" : " }");
+ writer.Write(first ? "}" : " }");
}
- private void WriteStructFieldValue(StringBuilder builder, IMessage message)
+ private void WriteStructFieldValue(TextWriter writer, IMessage message)
{
var specifiedField = message.Descriptor.Oneofs[0].Accessor.GetCaseFieldDescriptor(message);
if (specifiedField == null)
@@ -553,56 +651,48 @@ namespace Google.Protobuf
case Value.BoolValueFieldNumber:
case Value.StringValueFieldNumber:
case Value.NumberValueFieldNumber:
- WriteValue(builder, value);
+ WriteValue(writer, value);
return;
case Value.StructValueFieldNumber:
case Value.ListValueFieldNumber:
// Structs and ListValues are nested messages, and already well-known types.
var nestedMessage = (IMessage) specifiedField.Accessor.GetValue(message);
- WriteWellKnownTypeValue(builder, nestedMessage.Descriptor, nestedMessage, true);
+ WriteWellKnownTypeValue(writer, nestedMessage.Descriptor, nestedMessage);
return;
case Value.NullValueFieldNumber:
- WriteNull(builder);
+ WriteNull(writer);
return;
default:
throw new InvalidOperationException("Unexpected case in struct field: " + specifiedField.FieldNumber);
}
}
- internal void WriteList(StringBuilder builder, IList list)
+ internal void WriteList(TextWriter writer, IList list)
{
- builder.Append("[ ");
+ writer.Write("[ ");
bool first = true;
foreach (var value in list)
{
- if (!CanWriteSingleValue(value))
- {
- continue;
- }
if (!first)
{
- builder.Append(", ");
+ writer.Write(PropertySeparator);
}
- WriteValue(builder, value);
+ WriteValue(writer, value);
first = false;
}
- builder.Append(first ? "]" : " ]");
+ writer.Write(first ? "]" : " ]");
}
- internal void WriteDictionary(StringBuilder builder, IDictionary dictionary)
+ internal void WriteDictionary(TextWriter writer, IDictionary dictionary)
{
- builder.Append("{ ");
+ writer.Write("{ ");
bool first = true;
// This will box each pair. Could use IDictionaryEnumerator, but that's ugly in terms of disposal.
foreach (DictionaryEntry pair in dictionary)
{
- if (!CanWriteSingleValue(pair.Value))
- {
- continue;
- }
if (!first)
{
- builder.Append(", ");
+ writer.Write(PropertySeparator);
}
string keyText;
if (pair.Key is string)
@@ -625,12 +715,12 @@ namespace Google.Protobuf
}
throw new ArgumentException("Unhandled dictionary key type: " + pair.Key.GetType());
}
- WriteString(builder, keyText);
- builder.Append(": ");
- WriteValue(builder, pair.Value);
+ WriteString(writer, keyText);
+ writer.Write(NameValueSeparator);
+ WriteValue(writer, pair.Value);
first = false;
}
- builder.Append(first ? "}" : " }");
+ writer.Write(first ? "}" : " }");
}
/// <summary>
@@ -653,24 +743,15 @@ namespace Google.Protobuf
/// <remarks>
/// Other than surrogate pair handling, this code is mostly taken from src/google/protobuf/util/internal/json_escaping.cc.
/// </remarks>
- private void WriteString(StringBuilder builder, string text)
- {
- builder.Append('"');
- AppendEscapedString(builder, text);
- builder.Append('"');
- }
-
- /// <summary>
- /// Appends the given text to the string builder, escaping as required.
- /// </summary>
- private void AppendEscapedString(StringBuilder builder, string text)
+ internal static void WriteString(TextWriter writer, string text)
{
+ writer.Write('"');
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if (c < 0xa0)
{
- builder.Append(CommonRepresentations[c]);
+ writer.Write(CommonRepresentations[c]);
continue;
}
if (char.IsHighSurrogate(c))
@@ -682,8 +763,8 @@ namespace Google.Protobuf
{
throw new ArgumentException("String contains low surrogate not followed by high surrogate");
}
- HexEncodeUtf16CodeUnit(builder, c);
- HexEncodeUtf16CodeUnit(builder, text[i]);
+ HexEncodeUtf16CodeUnit(writer, c);
+ HexEncodeUtf16CodeUnit(writer, text[i]);
continue;
}
else if (char.IsLowSurrogate(c))
@@ -704,7 +785,7 @@ namespace Google.Protobuf
case 0x070f: // Syriac abbreviation mark
case 0x17b4: // Khmer vowel inherent Aq
case 0x17b5: // Khmer vowel inherent Aa
- HexEncodeUtf16CodeUnit(builder, c);
+ HexEncodeUtf16CodeUnit(writer, c);
break;
default:
@@ -714,26 +795,27 @@ namespace Google.Protobuf
(c >= 0x2060 && c <= 0x2064) || // Invisible etc.
(c >= 0x206a && c <= 0x206f))
{
- HexEncodeUtf16CodeUnit(builder, c);
+ HexEncodeUtf16CodeUnit(writer, c);
}
else
{
// No handling of surrogates here - that's done earlier
- builder.Append(c);
+ writer.Write(c);
}
break;
}
}
+ writer.Write('"');
}
private const string Hex = "0123456789abcdef";
- private static void HexEncodeUtf16CodeUnit(StringBuilder builder, char c)
+ private static void HexEncodeUtf16CodeUnit(TextWriter writer, char c)
{
- builder.Append("\\u");
- builder.Append(Hex[(c >> 12) & 0xf]);
- builder.Append(Hex[(c >> 8) & 0xf]);
- builder.Append(Hex[(c >> 4) & 0xf]);
- builder.Append(Hex[(c >> 0) & 0xf]);
+ writer.Write("\\u");
+ writer.Write(Hex[(c >> 12) & 0xf]);
+ writer.Write(Hex[(c >> 8) & 0xf]);
+ writer.Write(Hex[(c >> 4) & 0xf]);
+ writer.Write(Hex[(c >> 0) & 0xf]);
}
/// <summary>
@@ -741,30 +823,90 @@ namespace Google.Protobuf
/// </summary>
public sealed class Settings
{
- private static readonly Settings defaultInstance = new Settings(false);
-
/// <summary>
/// Default settings, as used by <see cref="JsonFormatter.Default"/>
/// </summary>
- public static Settings Default { get { return defaultInstance; } }
-
- private readonly bool formatDefaultValues;
+ public static Settings Default { get; }
+ // Workaround for the Mono compiler complaining about XML comments not being on
+ // valid language elements.
+ static Settings()
+ {
+ Default = new Settings(false);
+ }
/// <summary>
/// Whether fields whose values are the default for the field type (e.g. 0 for integers)
/// should be formatted (true) or omitted (false).
/// </summary>
- public bool FormatDefaultValues { get { return formatDefaultValues; } }
+ public bool FormatDefaultValues { get; }
+
+ /// <summary>
+ /// The type registry used to format <see cref="Any"/> messages.
+ /// </summary>
+ public TypeRegistry TypeRegistry { get; }
+
+ // TODO: Work out how we're going to scale this to multiple settings. "WithXyz" methods?
/// <summary>
- /// Creates a new <see cref="Settings"/> object with the specified formatting of default values.
+ /// Creates a new <see cref="Settings"/> object with the specified formatting of default values
+ /// and an empty type registry.
/// </summary>
/// <param name="formatDefaultValues"><c>true</c> if default values (0, empty strings etc) should be formatted; <c>false</c> otherwise.</param>
- public Settings(bool formatDefaultValues)
+ public Settings(bool formatDefaultValues) : this(formatDefaultValues, TypeRegistry.Empty)
{
- this.formatDefaultValues = formatDefaultValues;
}
+
+ /// <summary>
+ /// Creates a new <see cref="Settings"/> object with the specified formatting of default values
+ /// and type registry.
+ /// </summary>
+ /// <param name="formatDefaultValues"><c>true</c> if default values (0, empty strings etc) should be formatted; <c>false</c> otherwise.</param>
+ /// <param name="typeRegistry">The <see cref="TypeRegistry"/> to use when formatting <see cref="Any"/> messages.</param>
+ public Settings(bool formatDefaultValues, TypeRegistry typeRegistry)
+ {
+ FormatDefaultValues = formatDefaultValues;
+ TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
+ }
+ }
+
+ // Effectively a cache of mapping from enum values to the original name as specified in the proto file,
+ // fetched by reflection.
+ // The need for this is unfortunate, as is its unbounded size, but realistically it shouldn't cause issues.
+ private static class OriginalEnumValueHelper
+ {
+ // TODO: In the future we might want to use ConcurrentDictionary, at the point where all
+ // the platforms we target have it.
+ private static readonly Dictionary<System.Type, Dictionary<object, string>> dictionaries
+ = new Dictionary<System.Type, Dictionary<object, string>>();
+
+ internal static string GetOriginalName(object value)
+ {
+ var enumType = value.GetType();
+ Dictionary<object, string> nameMapping;
+ lock (dictionaries)
+ {
+ if (!dictionaries.TryGetValue(enumType, out nameMapping))
+ {
+ nameMapping = GetNameMapping(enumType);
+ dictionaries[enumType] = nameMapping;
+ }
+ }
+
+ string originalName;
+ // If this returns false, originalName will be null, which is what we want.
+ nameMapping.TryGetValue(value, out originalName);
+ return originalName;
+ }
+
+ private static Dictionary<object, string> GetNameMapping(System.Type enumType) =>
+ enumType.GetTypeInfo().DeclaredFields
+ .Where(f => f.IsStatic)
+ .ToDictionary(f => f.GetValue(null),
+ f => f.GetCustomAttributes<OriginalNameAttribute>()
+ .FirstOrDefault()
+ // If the attribute hasn't been applied, fall back to the name of the field.
+ ?.Name ?? f.Name);
}
}
}
diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs
new file mode 100644
index 00000000..d738ebb0
--- /dev/null
+++ b/csharp/src/Google.Protobuf/JsonParser.cs
@@ -0,0 +1,1018 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 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.
+#endregion
+
+using Google.Protobuf.Reflection;
+using Google.Protobuf.WellKnownTypes;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Reflection-based converter from JSON to messages.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Instances of this class are thread-safe, with no mutable state.
+ /// </para>
+ /// <para>
+ /// This is a simple start to get JSON parsing working. As it's reflection-based,
+ /// it's not as quick as baking calls into generated messages - but is a simpler implementation.
+ /// (This code is generally not heavily optimized.)
+ /// </para>
+ /// </remarks>
+ public sealed class JsonParser
+ {
+ // Note: using 0-9 instead of \d to ensure no non-ASCII digits.
+ // This regex isn't a complete validator, but will remove *most* invalid input. We rely on parsing to do the rest.
+ private static readonly Regex TimestampRegex = new Regex(@"^(?<datetime>[0-9]{4}-[01][0-9]-[0-3][0-9]T[012][0-9]:[0-5][0-9]:[0-5][0-9])(?<subseconds>\.[0-9]{1,9})?(?<offset>(Z|[+-][0-1][0-9]:[0-5][0-9]))$", FrameworkPortability.CompiledRegexWhereAvailable);
+ private static readonly Regex DurationRegex = new Regex(@"^(?<sign>-)?(?<int>[0-9]{1,12})(?<subseconds>\.[0-9]{1,9})?s$", FrameworkPortability.CompiledRegexWhereAvailable);
+ private static readonly int[] SubsecondScalingFactors = { 0, 100000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 };
+ private static readonly char[] FieldMaskPathSeparators = new[] { ',' };
+
+ private static readonly JsonParser defaultInstance = new JsonParser(Settings.Default);
+
+ // TODO: Consider introducing a class containing parse state of the parser, tokenizer and depth. That would simplify these handlers
+ // and the signatures of various methods.
+ private static readonly Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>>
+ WellKnownTypeHandlers = new Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>>
+ {
+ { Timestamp.Descriptor.FullName, (parser, message, tokenizer) => MergeTimestamp(message, tokenizer.Next()) },
+ { Duration.Descriptor.FullName, (parser, message, tokenizer) => MergeDuration(message, tokenizer.Next()) },
+ { Value.Descriptor.FullName, (parser, message, tokenizer) => parser.MergeStructValue(message, tokenizer) },
+ { ListValue.Descriptor.FullName, (parser, message, tokenizer) =>
+ parser.MergeRepeatedField(message, message.Descriptor.Fields[ListValue.ValuesFieldNumber], tokenizer) },
+ { Struct.Descriptor.FullName, (parser, message, tokenizer) => parser.MergeStruct(message, tokenizer) },
+ { Any.Descriptor.FullName, (parser, message, tokenizer) => parser.MergeAny(message, tokenizer) },
+ { FieldMask.Descriptor.FullName, (parser, message, tokenizer) => MergeFieldMask(message, tokenizer.Next()) },
+ { Int32Value.Descriptor.FullName, MergeWrapperField },
+ { Int64Value.Descriptor.FullName, MergeWrapperField },
+ { UInt32Value.Descriptor.FullName, MergeWrapperField },
+ { UInt64Value.Descriptor.FullName, MergeWrapperField },
+ { FloatValue.Descriptor.FullName, MergeWrapperField },
+ { DoubleValue.Descriptor.FullName, MergeWrapperField },
+ { BytesValue.Descriptor.FullName, MergeWrapperField },
+ { StringValue.Descriptor.FullName, MergeWrapperField }
+ };
+
+ // Convenience method to avoid having to repeat the same code multiple times in the above
+ // dictionary initialization.
+ private static void MergeWrapperField(JsonParser parser, IMessage message, JsonTokenizer tokenizer)
+ {
+ parser.MergeField(message, message.Descriptor.Fields[WrappersReflection.WrapperValueFieldNumber], tokenizer);
+ }
+
+ /// <summary>
+ /// Returns a formatter using the default settings.
+ /// </summary>
+ public static JsonParser Default { get { return defaultInstance; } }
+
+ private readonly Settings settings;
+
+ /// <summary>
+ /// Creates a new formatted with the given settings.
+ /// </summary>
+ /// <param name="settings">The settings.</param>
+ public JsonParser(Settings settings)
+ {
+ this.settings = settings;
+ }
+
+ /// <summary>
+ /// Parses <paramref name="json"/> and merges the information into the given message.
+ /// </summary>
+ /// <param name="message">The message to merge the JSON information into.</param>
+ /// <param name="json">The JSON to parse.</param>
+ internal void Merge(IMessage message, string json)
+ {
+ Merge(message, new StringReader(json));
+ }
+
+ /// <summary>
+ /// Parses JSON read from <paramref name="jsonReader"/> and merges the information into the given message.
+ /// </summary>
+ /// <param name="message">The message to merge the JSON information into.</param>
+ /// <param name="jsonReader">Reader providing the JSON to parse.</param>
+ internal void Merge(IMessage message, TextReader jsonReader)
+ {
+ var tokenizer = JsonTokenizer.FromTextReader(jsonReader);
+ Merge(message, tokenizer);
+ var lastToken = tokenizer.Next();
+ if (lastToken != JsonToken.EndDocument)
+ {
+ throw new InvalidProtocolBufferException("Expected end of JSON after object");
+ }
+ }
+
+ /// <summary>
+ /// Merges the given message using data from the given tokenizer. In most cases, the next
+ /// token should be a "start object" token, but wrapper types and nullity can invalidate
+ /// that assumption. This is implemented as an LL(1) recursive descent parser over the stream
+ /// of tokens provided by the tokenizer. This token stream is assumed to be valid JSON, with the
+ /// tokenizer performing that validation - but not every token stream is valid "protobuf JSON".
+ /// </summary>
+ private void Merge(IMessage message, JsonTokenizer tokenizer)
+ {
+ if (tokenizer.ObjectDepth > settings.RecursionLimit)
+ {
+ throw InvalidProtocolBufferException.JsonRecursionLimitExceeded();
+ }
+ if (message.Descriptor.IsWellKnownType)
+ {
+ Action<JsonParser, IMessage, JsonTokenizer> handler;
+ if (WellKnownTypeHandlers.TryGetValue(message.Descriptor.FullName, out handler))
+ {
+ handler(this, message, tokenizer);
+ return;
+ }
+ // Well-known types with no special handling continue in the normal way.
+ }
+ var token = tokenizer.Next();
+ if (token.Type != JsonToken.TokenType.StartObject)
+ {
+ throw new InvalidProtocolBufferException("Expected an object");
+ }
+ var descriptor = message.Descriptor;
+ var jsonFieldMap = descriptor.Fields.ByJsonName();
+ // All the oneof fields we've already accounted for - we can only see each of them once.
+ // The set is created lazily to avoid the overhead of creating a set for every message
+ // we parsed, when oneofs are relatively rare.
+ HashSet<OneofDescriptor> seenOneofs = null;
+ while (true)
+ {
+ token = tokenizer.Next();
+ if (token.Type == JsonToken.TokenType.EndObject)
+ {
+ return;
+ }
+ if (token.Type != JsonToken.TokenType.Name)
+ {
+ throw new InvalidOperationException("Unexpected token type " + token.Type);
+ }
+ string name = token.StringValue;
+ FieldDescriptor field;
+ if (jsonFieldMap.TryGetValue(name, out field))
+ {
+ if (field.ContainingOneof != null)
+ {
+ if (seenOneofs == null)
+ {
+ seenOneofs = new HashSet<OneofDescriptor>();
+ }
+ if (!seenOneofs.Add(field.ContainingOneof))
+ {
+ throw new InvalidProtocolBufferException($"Multiple values specified for oneof {field.ContainingOneof.Name}");
+ }
+ }
+ MergeField(message, field, tokenizer);
+ }
+ else
+ {
+ // TODO: Is this what we want to do? If not, we'll need to skip the value,
+ // which may be an object or array. (We might want to put code in the tokenizer
+ // to do that.)
+ throw new InvalidProtocolBufferException("Unknown field: " + name);
+ }
+ }
+ }
+
+ private void MergeField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)
+ {
+ var token = tokenizer.Next();
+ if (token.Type == JsonToken.TokenType.Null)
+ {
+ // Clear the field if we see a null token, unless it's for a singular field of type
+ // google.protobuf.Value.
+ // Note: different from Java API, which just ignores it.
+ // TODO: Bring it more in line? Discuss...
+ if (field.IsMap || field.IsRepeated || !IsGoogleProtobufValueField(field))
+ {
+ field.Accessor.Clear(message);
+ return;
+ }
+ }
+ tokenizer.PushBack(token);
+
+ if (field.IsMap)
+ {
+ MergeMapField(message, field, tokenizer);
+ }
+ else if (field.IsRepeated)
+ {
+ MergeRepeatedField(message, field, tokenizer);
+ }
+ else
+ {
+ var value = ParseSingleValue(field, tokenizer);
+ field.Accessor.SetValue(message, value);
+ }
+ }
+
+ private void MergeRepeatedField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)
+ {
+ var token = tokenizer.Next();
+ if (token.Type != JsonToken.TokenType.StartArray)
+ {
+ throw new InvalidProtocolBufferException("Repeated field value was not an array. Token type: " + token.Type);
+ }
+
+ IList list = (IList) field.Accessor.GetValue(message);
+ while (true)
+ {
+ token = tokenizer.Next();
+ if (token.Type == JsonToken.TokenType.EndArray)
+ {
+ return;
+ }
+ tokenizer.PushBack(token);
+ if (token.Type == JsonToken.TokenType.Null)
+ {
+ throw new InvalidProtocolBufferException("Repeated field elements cannot be null");
+ }
+ list.Add(ParseSingleValue(field, tokenizer));
+ }
+ }
+
+ private void MergeMapField(IMessage message, FieldDescriptor field, JsonTokenizer tokenizer)
+ {
+ // Map fields are always objects, even if the values are well-known types: ParseSingleValue handles those.
+ var token = tokenizer.Next();
+ if (token.Type != JsonToken.TokenType.StartObject)
+ {
+ throw new InvalidProtocolBufferException("Expected an object to populate a map");
+ }
+
+ var type = field.MessageType;
+ var keyField = type.FindFieldByNumber(1);
+ var valueField = type.FindFieldByNumber(2);
+ if (keyField == null || valueField == null)
+ {
+ throw new InvalidProtocolBufferException("Invalid map field: " + field.FullName);
+ }
+ IDictionary dictionary = (IDictionary) field.Accessor.GetValue(message);
+
+ while (true)
+ {
+ token = tokenizer.Next();
+ if (token.Type == JsonToken.TokenType.EndObject)
+ {
+ return;
+ }
+ object key = ParseMapKey(keyField, token.StringValue);
+ object value = ParseSingleValue(valueField, tokenizer);
+ if (value == null)
+ {
+ throw new InvalidProtocolBufferException("Map values must not be null");
+ }
+ dictionary[key] = value;
+ }
+ }
+
+ private static bool IsGoogleProtobufValueField(FieldDescriptor field)
+ {
+ return field.FieldType == FieldType.Message &&
+ field.MessageType.FullName == Value.Descriptor.FullName;
+ }
+
+ private object ParseSingleValue(FieldDescriptor field, JsonTokenizer tokenizer)
+ {
+ var token = tokenizer.Next();
+ if (token.Type == JsonToken.TokenType.Null)
+ {
+ // TODO: In order to support dynamic messages, we should really build this up
+ // dynamically.
+ if (IsGoogleProtobufValueField(field))
+ {
+ return Value.ForNull();
+ }
+ return null;
+ }
+
+ var fieldType = field.FieldType;
+ if (fieldType == FieldType.Message)
+ {
+ // Parse wrapper types as their constituent types.
+ // TODO: What does this mean for null?
+ if (field.MessageType.IsWrapperType)
+ {
+ field = field.MessageType.Fields[WrappersReflection.WrapperValueFieldNumber];
+ fieldType = field.FieldType;
+ }
+ else
+ {
+ // TODO: Merge the current value in message? (Public API currently doesn't make this relevant as we don't expose merging.)
+ tokenizer.PushBack(token);
+ IMessage subMessage = NewMessageForField(field);
+ Merge(subMessage, tokenizer);
+ return subMessage;
+ }
+ }
+
+ switch (token.Type)
+ {
+ case JsonToken.TokenType.True:
+ case JsonToken.TokenType.False:
+ if (fieldType == FieldType.Bool)
+ {
+ return token.Type == JsonToken.TokenType.True;
+ }
+ // Fall through to "we don't support this type for this case"; could duplicate the behaviour of the default
+ // case instead, but this way we'd only need to change one place.
+ goto default;
+ case JsonToken.TokenType.StringValue:
+ return ParseSingleStringValue(field, token.StringValue);
+ // Note: not passing the number value itself here, as we may end up storing the string value in the token too.
+ case JsonToken.TokenType.Number:
+ return ParseSingleNumberValue(field, token);
+ case JsonToken.TokenType.Null:
+ throw new NotImplementedException("Haven't worked out what to do for null yet");
+ default:
+ throw new InvalidProtocolBufferException("Unsupported JSON token type " + token.Type + " for field type " + fieldType);
+ }
+ }
+
+ /// <summary>
+ /// Parses <paramref name="json"/> into a new message.
+ /// </summary>
+ /// <typeparam name="T">The type of message to create.</typeparam>
+ /// <param name="json">The JSON to parse.</param>
+ /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception>
+ /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
+ public T Parse<T>(string json) where T : IMessage, new()
+ {
+ ProtoPreconditions.CheckNotNull(json, nameof(json));
+ return Parse<T>(new StringReader(json));
+ }
+
+ /// <summary>
+ /// Parses JSON read from <paramref name="jsonReader"/> into a new message.
+ /// </summary>
+ /// <typeparam name="T">The type of message to create.</typeparam>
+ /// <param name="jsonReader">Reader providing the JSON to parse.</param>
+ /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception>
+ /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
+ public T Parse<T>(TextReader jsonReader) where T : IMessage, new()
+ {
+ ProtoPreconditions.CheckNotNull(jsonReader, nameof(jsonReader));
+ T message = new T();
+ Merge(message, jsonReader);
+ return message;
+ }
+
+ /// <summary>
+ /// Parses <paramref name="json"/> into a new message.
+ /// </summary>
+ /// <param name="json">The JSON to parse.</param>
+ /// <param name="descriptor">Descriptor of message type to parse.</param>
+ /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception>
+ /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
+ public IMessage Parse(string json, MessageDescriptor descriptor)
+ {
+ ProtoPreconditions.CheckNotNull(json, nameof(json));
+ ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor));
+ return Parse(new StringReader(json), descriptor);
+ }
+
+ /// <summary>
+ /// Parses JSON read from <paramref name="jsonReader"/> into a new message.
+ /// </summary>
+ /// <param name="jsonReader">Reader providing the JSON to parse.</param>
+ /// <param name="descriptor">Descriptor of message type to parse.</param>
+ /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception>
+ /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
+ public IMessage Parse(TextReader jsonReader, MessageDescriptor descriptor)
+ {
+ ProtoPreconditions.CheckNotNull(jsonReader, nameof(jsonReader));
+ ProtoPreconditions.CheckNotNull(descriptor, nameof(descriptor));
+ IMessage message = descriptor.Parser.CreateTemplate();
+ Merge(message, jsonReader);
+ return message;
+ }
+
+ private void MergeStructValue(IMessage message, JsonTokenizer tokenizer)
+ {
+ var firstToken = tokenizer.Next();
+ var fields = message.Descriptor.Fields;
+ switch (firstToken.Type)
+ {
+ case JsonToken.TokenType.Null:
+ fields[Value.NullValueFieldNumber].Accessor.SetValue(message, 0);
+ return;
+ case JsonToken.TokenType.StringValue:
+ fields[Value.StringValueFieldNumber].Accessor.SetValue(message, firstToken.StringValue);
+ return;
+ case JsonToken.TokenType.Number:
+ fields[Value.NumberValueFieldNumber].Accessor.SetValue(message, firstToken.NumberValue);
+ return;
+ case JsonToken.TokenType.False:
+ case JsonToken.TokenType.True:
+ fields[Value.BoolValueFieldNumber].Accessor.SetValue(message, firstToken.Type == JsonToken.TokenType.True);
+ return;
+ case JsonToken.TokenType.StartObject:
+ {
+ var field = fields[Value.StructValueFieldNumber];
+ var structMessage = NewMessageForField(field);
+ tokenizer.PushBack(firstToken);
+ Merge(structMessage, tokenizer);
+ field.Accessor.SetValue(message, structMessage);
+ return;
+ }
+ case JsonToken.TokenType.StartArray:
+ {
+ var field = fields[Value.ListValueFieldNumber];
+ var list = NewMessageForField(field);
+ tokenizer.PushBack(firstToken);
+ Merge(list, tokenizer);
+ field.Accessor.SetValue(message, list);
+ return;
+ }
+ default:
+ throw new InvalidOperationException("Unexpected token type: " + firstToken.Type);
+ }
+ }
+
+ private void MergeStruct(IMessage message, JsonTokenizer tokenizer)
+ {
+ var token = tokenizer.Next();
+ if (token.Type != JsonToken.TokenType.StartObject)
+ {
+ throw new InvalidProtocolBufferException("Expected object value for Struct");
+ }
+ tokenizer.PushBack(token);
+
+ var field = message.Descriptor.Fields[Struct.FieldsFieldNumber];
+ MergeMapField(message, field, tokenizer);
+ }
+
+ private void MergeAny(IMessage message, JsonTokenizer tokenizer)
+ {
+ // Record the token stream until we see the @type property. At that point, we can take the value, consult
+ // the type registry for the relevant message, and replay the stream, omitting the @type property.
+ var tokens = new List<JsonToken>();
+
+ var token = tokenizer.Next();
+ if (token.Type != JsonToken.TokenType.StartObject)
+ {
+ throw new InvalidProtocolBufferException("Expected object value for Any");
+ }
+ int typeUrlObjectDepth = tokenizer.ObjectDepth;
+
+ // The check for the property depth protects us from nested Any values which occur before the type URL
+ // for *this* Any.
+ while (token.Type != JsonToken.TokenType.Name ||
+ token.StringValue != JsonFormatter.AnyTypeUrlField ||
+ tokenizer.ObjectDepth != typeUrlObjectDepth)
+ {
+ tokens.Add(token);
+ token = tokenizer.Next();
+
+ if (tokenizer.ObjectDepth < typeUrlObjectDepth)
+ {
+ throw new InvalidProtocolBufferException("Any message with no @type");
+ }
+ }
+
+ // Don't add the @type property or its value to the recorded token list
+ token = tokenizer.Next();
+ if (token.Type != JsonToken.TokenType.StringValue)
+ {
+ throw new InvalidProtocolBufferException("Expected string value for Any.@type");
+ }
+ string typeUrl = token.StringValue;
+ string typeName = Any.GetTypeName(typeUrl);
+
+ MessageDescriptor descriptor = settings.TypeRegistry.Find(typeName);
+ if (descriptor == null)
+ {
+ throw new InvalidOperationException($"Type registry has no descriptor for type name '{typeName}'");
+ }
+
+ // Now replay the token stream we've already read and anything that remains of the object, just parsing it
+ // as normal. Our original tokenizer should end up at the end of the object.
+ var replay = JsonTokenizer.FromReplayedTokens(tokens, tokenizer);
+ var body = descriptor.Parser.CreateTemplate();
+ if (descriptor.IsWellKnownType)
+ {
+ MergeWellKnownTypeAnyBody(body, replay);
+ }
+ else
+ {
+ Merge(body, replay);
+ }
+ var data = body.ToByteString();
+
+ // Now that we have the message data, we can pack it into an Any (the message received as a parameter).
+ message.Descriptor.Fields[Any.TypeUrlFieldNumber].Accessor.SetValue(message, typeUrl);
+ message.Descriptor.Fields[Any.ValueFieldNumber].Accessor.SetValue(message, data);
+ }
+
+ // Well-known types end up in a property called "value" in the JSON. As there's no longer a @type property
+ // in the given JSON token stream, we should *only* have tokens of start-object, name("value"), the value
+ // itself, and then end-object.
+ private void MergeWellKnownTypeAnyBody(IMessage body, JsonTokenizer tokenizer)
+ {
+ var token = tokenizer.Next(); // Definitely start-object; checked in previous method
+ token = tokenizer.Next();
+ // TODO: What about an absent Int32Value, for example?
+ if (token.Type != JsonToken.TokenType.Name || token.StringValue != JsonFormatter.AnyWellKnownTypeValueField)
+ {
+ throw new InvalidProtocolBufferException($"Expected '{JsonFormatter.AnyWellKnownTypeValueField}' property for well-known type Any body");
+ }
+ Merge(body, tokenizer);
+ token = tokenizer.Next();
+ if (token.Type != JsonToken.TokenType.EndObject)
+ {
+ throw new InvalidProtocolBufferException($"Expected end-object token after @type/value for well-known type");
+ }
+ }
+
+ #region Utility methods which don't depend on the state (or settings) of the parser.
+ private static object ParseMapKey(FieldDescriptor field, string keyText)
+ {
+ switch (field.FieldType)
+ {
+ case FieldType.Bool:
+ if (keyText == "true")
+ {
+ return true;
+ }
+ if (keyText == "false")
+ {
+ return false;
+ }
+ throw new InvalidProtocolBufferException("Invalid string for bool map key: " + keyText);
+ case FieldType.String:
+ return keyText;
+ case FieldType.Int32:
+ case FieldType.SInt32:
+ case FieldType.SFixed32:
+ return ParseNumericString(keyText, int.Parse);
+ case FieldType.UInt32:
+ case FieldType.Fixed32:
+ return ParseNumericString(keyText, uint.Parse);
+ case FieldType.Int64:
+ case FieldType.SInt64:
+ case FieldType.SFixed64:
+ return ParseNumericString(keyText, long.Parse);
+ case FieldType.UInt64:
+ case FieldType.Fixed64:
+ return ParseNumericString(keyText, ulong.Parse);
+ default:
+ throw new InvalidProtocolBufferException("Invalid field type for map: " + field.FieldType);
+ }
+ }
+
+ private static object ParseSingleNumberValue(FieldDescriptor field, JsonToken token)
+ {
+ double value = token.NumberValue;
+ checked
+ {
+ try
+ {
+ switch (field.FieldType)
+ {
+ case FieldType.Int32:
+ case FieldType.SInt32:
+ case FieldType.SFixed32:
+ CheckInteger(value);
+ return (int) value;
+ case FieldType.UInt32:
+ case FieldType.Fixed32:
+ CheckInteger(value);
+ return (uint) value;
+ case FieldType.Int64:
+ case FieldType.SInt64:
+ case FieldType.SFixed64:
+ CheckInteger(value);
+ return (long) value;
+ case FieldType.UInt64:
+ case FieldType.Fixed64:
+ CheckInteger(value);
+ return (ulong) value;
+ case FieldType.Double:
+ return value;
+ case FieldType.Float:
+ if (double.IsNaN(value))
+ {
+ return float.NaN;
+ }
+ if (value > float.MaxValue || value < float.MinValue)
+ {
+ if (double.IsPositiveInfinity(value))
+ {
+ return float.PositiveInfinity;
+ }
+ if (double.IsNegativeInfinity(value))
+ {
+ return float.NegativeInfinity;
+ }
+ throw new InvalidProtocolBufferException($"Value out of range: {value}");
+ }
+ return (float) value;
+ case FieldType.Enum:
+ CheckInteger(value);
+ // Just return it as an int, and let the CLR convert it.
+ // Note that we deliberately don't check that it's a known value.
+ return (int) value;
+ default:
+ throw new InvalidProtocolBufferException($"Unsupported conversion from JSON number for field type {field.FieldType}");
+ }
+ }
+ catch (OverflowException)
+ {
+ throw new InvalidProtocolBufferException($"Value out of range: {value}");
+ }
+ }
+ }
+
+ private static void CheckInteger(double value)
+ {
+ if (double.IsInfinity(value) || double.IsNaN(value))
+ {
+ throw new InvalidProtocolBufferException($"Value not an integer: {value}");
+ }
+ if (value != Math.Floor(value))
+ {
+ throw new InvalidProtocolBufferException($"Value not an integer: {value}");
+ }
+ }
+
+ private static object ParseSingleStringValue(FieldDescriptor field, string text)
+ {
+ switch (field.FieldType)
+ {
+ case FieldType.String:
+ return text;
+ case FieldType.Bytes:
+ try
+ {
+ return ByteString.FromBase64(text);
+ }
+ catch (FormatException e)
+ {
+ throw InvalidProtocolBufferException.InvalidBase64(e);
+ }
+ case FieldType.Int32:
+ case FieldType.SInt32:
+ case FieldType.SFixed32:
+ return ParseNumericString(text, int.Parse);
+ case FieldType.UInt32:
+ case FieldType.Fixed32:
+ return ParseNumericString(text, uint.Parse);
+ case FieldType.Int64:
+ case FieldType.SInt64:
+ case FieldType.SFixed64:
+ return ParseNumericString(text, long.Parse);
+ case FieldType.UInt64:
+ case FieldType.Fixed64:
+ return ParseNumericString(text, ulong.Parse);
+ case FieldType.Double:
+ double d = ParseNumericString(text, double.Parse);
+ ValidateInfinityAndNan(text, double.IsPositiveInfinity(d), double.IsNegativeInfinity(d), double.IsNaN(d));
+ return d;
+ case FieldType.Float:
+ float f = ParseNumericString(text, float.Parse);
+ ValidateInfinityAndNan(text, float.IsPositiveInfinity(f), float.IsNegativeInfinity(f), float.IsNaN(f));
+ return f;
+ case FieldType.Enum:
+ var enumValue = field.EnumType.FindValueByName(text);
+ if (enumValue == null)
+ {
+ throw new InvalidProtocolBufferException($"Invalid enum value: {text} for enum type: {field.EnumType.FullName}");
+ }
+ // Just return it as an int, and let the CLR convert it.
+ return enumValue.Number;
+ default:
+ throw new InvalidProtocolBufferException($"Unsupported conversion from JSON string for field type {field.FieldType}");
+ }
+ }
+
+ /// <summary>
+ /// Creates a new instance of the message type for the given field.
+ /// </summary>
+ private static IMessage NewMessageForField(FieldDescriptor field)
+ {
+ return field.MessageType.Parser.CreateTemplate();
+ }
+
+ private static T ParseNumericString<T>(string text, Func<string, NumberStyles, IFormatProvider, T> parser)
+ {
+ // Can't prohibit this with NumberStyles.
+ if (text.StartsWith("+"))
+ {
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
+ }
+ if (text.StartsWith("0") && text.Length > 1)
+ {
+ if (text[1] >= '0' && text[1] <= '9')
+ {
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
+ }
+ }
+ else if (text.StartsWith("-0") && text.Length > 2)
+ {
+ if (text[2] >= '0' && text[2] <= '9')
+ {
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
+ }
+ }
+ try
+ {
+ return parser(text, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture);
+ }
+ catch (FormatException)
+ {
+ throw new InvalidProtocolBufferException($"Invalid numeric value for type: {text}");
+ }
+ catch (OverflowException)
+ {
+ throw new InvalidProtocolBufferException($"Value out of range: {text}");
+ }
+ }
+
+ /// <summary>
+ /// Checks that any infinite/NaN values originated from the correct text.
+ /// This corrects the lenient whitespace handling of double.Parse/float.Parse, as well as the
+ /// way that Mono parses out-of-range values as infinity.
+ /// </summary>
+ private static void ValidateInfinityAndNan(string text, bool isPositiveInfinity, bool isNegativeInfinity, bool isNaN)
+ {
+ if ((isPositiveInfinity && text != "Infinity") ||
+ (isNegativeInfinity && text != "-Infinity") ||
+ (isNaN && text != "NaN"))
+ {
+ throw new InvalidProtocolBufferException($"Invalid numeric value: {text}");
+ }
+ }
+
+ private static void MergeTimestamp(IMessage message, JsonToken token)
+ {
+ if (token.Type != JsonToken.TokenType.StringValue)
+ {
+ throw new InvalidProtocolBufferException("Expected string value for Timestamp");
+ }
+ var match = TimestampRegex.Match(token.StringValue);
+ if (!match.Success)
+ {
+ throw new InvalidProtocolBufferException($"Invalid Timestamp value: {token.StringValue}");
+ }
+ var dateTime = match.Groups["datetime"].Value;
+ var subseconds = match.Groups["subseconds"].Value;
+ var offset = match.Groups["offset"].Value;
+
+ try
+ {
+ DateTime parsed = DateTime.ParseExact(
+ dateTime,
+ "yyyy-MM-dd'T'HH:mm:ss",
+ CultureInfo.InvariantCulture,
+ DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
+ // TODO: It would be nice not to have to create all these objects... easy to optimize later though.
+ Timestamp timestamp = Timestamp.FromDateTime(parsed);
+ int nanosToAdd = 0;
+ if (subseconds != "")
+ {
+ // This should always work, as we've got 1-9 digits.
+ int parsedFraction = int.Parse(subseconds.Substring(1), CultureInfo.InvariantCulture);
+ nanosToAdd = parsedFraction * SubsecondScalingFactors[subseconds.Length];
+ }
+ int secondsToAdd = 0;
+ if (offset != "Z")
+ {
+ // This is the amount we need to *subtract* from the local time to get to UTC - hence - => +1 and vice versa.
+ int sign = offset[0] == '-' ? 1 : -1;
+ int hours = int.Parse(offset.Substring(1, 2), CultureInfo.InvariantCulture);
+ int minutes = int.Parse(offset.Substring(4, 2));
+ int totalMinutes = hours * 60 + minutes;
+ if (totalMinutes > 18 * 60)
+ {
+ throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue);
+ }
+ if (totalMinutes == 0 && sign == 1)
+ {
+ // This is an offset of -00:00, which means "unknown local offset". It makes no sense for a timestamp.
+ throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue);
+ }
+ // We need to *subtract* the offset from local time to get UTC.
+ secondsToAdd = sign * totalMinutes * 60;
+ }
+ // Ensure we've got the right signs. Currently unnecessary, but easy to do.
+ if (secondsToAdd < 0 && nanosToAdd > 0)
+ {
+ secondsToAdd++;
+ nanosToAdd = nanosToAdd - Duration.NanosecondsPerSecond;
+ }
+ if (secondsToAdd != 0 || nanosToAdd != 0)
+ {
+ timestamp += new Duration { Nanos = nanosToAdd, Seconds = secondsToAdd };
+ // The resulting timestamp after offset change would be out of our expected range. Currently the Timestamp message doesn't validate this
+ // anywhere, but we shouldn't parse it.
+ if (timestamp.Seconds < Timestamp.UnixSecondsAtBclMinValue || timestamp.Seconds > Timestamp.UnixSecondsAtBclMaxValue)
+ {
+ throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue);
+ }
+ }
+ message.Descriptor.Fields[Timestamp.SecondsFieldNumber].Accessor.SetValue(message, timestamp.Seconds);
+ message.Descriptor.Fields[Timestamp.NanosFieldNumber].Accessor.SetValue(message, timestamp.Nanos);
+ }
+ catch (FormatException)
+ {
+ throw new InvalidProtocolBufferException("Invalid Timestamp value: " + token.StringValue);
+ }
+ }
+
+ private static void MergeDuration(IMessage message, JsonToken token)
+ {
+ if (token.Type != JsonToken.TokenType.StringValue)
+ {
+ throw new InvalidProtocolBufferException("Expected string value for Duration");
+ }
+ var match = DurationRegex.Match(token.StringValue);
+ if (!match.Success)
+ {
+ throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue);
+ }
+ var sign = match.Groups["sign"].Value;
+ var secondsText = match.Groups["int"].Value;
+ // Prohibit leading insignficant zeroes
+ if (secondsText[0] == '0' && secondsText.Length > 1)
+ {
+ throw new InvalidProtocolBufferException("Invalid Duration value: " + token.StringValue);
+ }
+ var subseconds = match.Groups["subseconds"].Value;
+ var multiplier = sign == "-" ? -1 : 1;
+
+ try
+ {
+ long seconds = long.Parse(secondsText, CultureInfo.InvariantCulture) * multiplier;
+ int nanos = 0;
+ if (subseconds != "")
+ {
+ // This should always work, as we've got 1-9 digits.
+ int parsedFraction = int.Parse(subseconds.Substring(1));
+ nanos = parsedFraction * SubsecondScalingFactors[subseconds.Length] * multiplier;
+ }
+ if (!Duration.IsNormalized(seconds, nanos))
+ {
+ throw new InvalidProtocolBufferException($"Invalid Duration value: {token.StringValue}");
+ }
+ message.Descriptor.Fields[Duration.SecondsFieldNumber].Accessor.SetValue(message, seconds);
+ message.Descriptor.Fields[Duration.NanosFieldNumber].Accessor.SetValue(message, nanos);
+ }
+ catch (FormatException)
+ {
+ throw new InvalidProtocolBufferException($"Invalid Duration value: {token.StringValue}");
+ }
+ }
+
+ private static void MergeFieldMask(IMessage message, JsonToken token)
+ {
+ if (token.Type != JsonToken.TokenType.StringValue)
+ {
+ throw new InvalidProtocolBufferException("Expected string value for FieldMask");
+ }
+ // TODO: Do we *want* to remove empty entries? Probably okay to treat "" as "no paths", but "foo,,bar"?
+ string[] jsonPaths = token.StringValue.Split(FieldMaskPathSeparators, StringSplitOptions.RemoveEmptyEntries);
+ IList messagePaths = (IList) message.Descriptor.Fields[FieldMask.PathsFieldNumber].Accessor.GetValue(message);
+ foreach (var path in jsonPaths)
+ {
+ messagePaths.Add(ToSnakeCase(path));
+ }
+ }
+
+ // Ported from src/google/protobuf/util/internal/utility.cc
+ private static string ToSnakeCase(string text)
+ {
+ var builder = new StringBuilder(text.Length * 2);
+ // Note: this is probably unnecessary now, but currently retained to be as close as possible to the
+ // C++, whilst still throwing an exception on underscores.
+ bool wasNotUnderscore = false; // Initialize to false for case 1 (below)
+ bool wasNotCap = false;
+
+ for (int i = 0; i < text.Length; i++)
+ {
+ char c = text[i];
+ if (c >= 'A' && c <= 'Z') // ascii_isupper
+ {
+ // Consider when the current character B is capitalized:
+ // 1) At beginning of input: "B..." => "b..."
+ // (e.g. "Biscuit" => "biscuit")
+ // 2) Following a lowercase: "...aB..." => "...a_b..."
+ // (e.g. "gBike" => "g_bike")
+ // 3) At the end of input: "...AB" => "...ab"
+ // (e.g. "GoogleLAB" => "google_lab")
+ // 4) Followed by a lowercase: "...ABc..." => "...a_bc..."
+ // (e.g. "GBike" => "g_bike")
+ if (wasNotUnderscore && // case 1 out
+ (wasNotCap || // case 2 in, case 3 out
+ (i + 1 < text.Length && // case 3 out
+ (text[i + 1] >= 'a' && text[i + 1] <= 'z')))) // ascii_islower(text[i + 1])
+ { // case 4 in
+ // We add an underscore for case 2 and case 4.
+ builder.Append('_');
+ }
+ // ascii_tolower, but we already know that c *is* an upper case ASCII character...
+ builder.Append((char) (c + 'a' - 'A'));
+ wasNotUnderscore = true;
+ wasNotCap = false;
+ }
+ else
+ {
+ builder.Append(c);
+ if (c == '_')
+ {
+ throw new InvalidProtocolBufferException($"Invalid field mask: {text}");
+ }
+ wasNotUnderscore = true;
+ wasNotCap = true;
+ }
+ }
+ return builder.ToString();
+ }
+ #endregion
+
+ /// <summary>
+ /// Settings controlling JSON parsing.
+ /// </summary>
+ public sealed class Settings
+ {
+ /// <summary>
+ /// Default settings, as used by <see cref="JsonParser.Default"/>. This has the same default
+ /// recursion limit as <see cref="CodedInputStream"/>, and an empty type registry.
+ /// </summary>
+ public static Settings Default { get; }
+
+ // Workaround for the Mono compiler complaining about XML comments not being on
+ // valid language elements.
+ static Settings()
+ {
+ Default = new Settings(CodedInputStream.DefaultRecursionLimit);
+ }
+
+ /// <summary>
+ /// The maximum depth of messages to parse. Note that this limit only applies to parsing
+ /// messages, not collections - so a message within a collection within a message only counts as
+ /// depth 2, not 3.
+ /// </summary>
+ public int RecursionLimit { get; }
+
+ /// <summary>
+ /// The type registry used to parse <see cref="Any"/> messages.
+ /// </summary>
+ public TypeRegistry TypeRegistry { get; }
+
+ /// <summary>
+ /// Creates a new <see cref="Settings"/> object with the specified recursion limit.
+ /// </summary>
+ /// <param name="recursionLimit">The maximum depth of messages to parse</param>
+ public Settings(int recursionLimit) : this(recursionLimit, TypeRegistry.Empty)
+ {
+ }
+
+ /// <summary>
+ /// Creates a new <see cref="Settings"/> object with the specified recursion limit and type registry.
+ /// </summary>
+ /// <param name="recursionLimit">The maximum depth of messages to parse</param>
+ /// <param name="typeRegistry">The type registry used to parse <see cref="Any"/> messages</param>
+ public Settings(int recursionLimit, TypeRegistry typeRegistry)
+ {
+ RecursionLimit = recursionLimit;
+ TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, nameof(typeRegistry));
+ }
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/JsonToken.cs b/csharp/src/Google.Protobuf/JsonToken.cs
new file mode 100644
index 00000000..6c0138cc
--- /dev/null
+++ b/csharp/src/Google.Protobuf/JsonToken.cs
@@ -0,0 +1,166 @@
+#region Copyright notice and license
+// 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.
+#endregion
+
+using System;
+
+namespace Google.Protobuf
+{
+ internal sealed class JsonToken : IEquatable<JsonToken>
+ {
+ // Tokens with no value can be reused.
+ private static readonly JsonToken _true = new JsonToken(TokenType.True);
+ private static readonly JsonToken _false = new JsonToken(TokenType.False);
+ private static readonly JsonToken _null = new JsonToken(TokenType.Null);
+ private static readonly JsonToken startObject = new JsonToken(TokenType.StartObject);
+ private static readonly JsonToken endObject = new JsonToken(TokenType.EndObject);
+ private static readonly JsonToken startArray = new JsonToken(TokenType.StartArray);
+ private static readonly JsonToken endArray = new JsonToken(TokenType.EndArray);
+ private static readonly JsonToken endDocument = new JsonToken(TokenType.EndDocument);
+
+ internal static JsonToken Null { get { return _null; } }
+ internal static JsonToken False { get { return _false; } }
+ internal static JsonToken True { get { return _true; } }
+ internal static JsonToken StartObject{ get { return startObject; } }
+ internal static JsonToken EndObject { get { return endObject; } }
+ internal static JsonToken StartArray { get { return startArray; } }
+ internal static JsonToken EndArray { get { return endArray; } }
+ internal static JsonToken EndDocument { get { return endDocument; } }
+
+ internal static JsonToken Name(string name)
+ {
+ return new JsonToken(TokenType.Name, stringValue: name);
+ }
+
+ internal static JsonToken Value(string value)
+ {
+ return new JsonToken(TokenType.StringValue, stringValue: value);
+ }
+
+ internal static JsonToken Value(double value)
+ {
+ return new JsonToken(TokenType.Number, numberValue: value);
+ }
+
+ internal enum TokenType
+ {
+ Null,
+ False,
+ True,
+ StringValue,
+ Number,
+ Name,
+ StartObject,
+ EndObject,
+ StartArray,
+ EndArray,
+ EndDocument
+ }
+
+ // A value is a string, number, array, object, null, true or false
+ // Arrays and objects have start/end
+ // A document consists of a value
+ // Objects are name/value sequences.
+
+ private readonly TokenType type;
+ private readonly string stringValue;
+ private readonly double numberValue;
+
+ internal TokenType Type { get { return type; } }
+ internal string StringValue { get { return stringValue; } }
+ internal double NumberValue { get { return numberValue; } }
+
+ private JsonToken(TokenType type, string stringValue = null, double numberValue = 0)
+ {
+ this.type = type;
+ this.stringValue = stringValue;
+ this.numberValue = numberValue;
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Equals(obj as JsonToken);
+ }
+
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hash = 17;
+ hash = hash * 31 + (int) type;
+ hash = hash * 31 + stringValue == null ? 0 : stringValue.GetHashCode();
+ hash = hash * 31 + numberValue.GetHashCode();
+ return hash;
+ }
+ }
+
+ public override string ToString()
+ {
+ switch (type)
+ {
+ case TokenType.Null:
+ return "null";
+ case TokenType.True:
+ return "true";
+ case TokenType.False:
+ return "false";
+ case TokenType.Name:
+ return "name (" + stringValue + ")";
+ case TokenType.StringValue:
+ return "value (" + stringValue + ")";
+ case TokenType.Number:
+ return "number (" + numberValue + ")";
+ case TokenType.StartObject:
+ return "start-object";
+ case TokenType.EndObject:
+ return "end-object";
+ case TokenType.StartArray:
+ return "start-array";
+ case TokenType.EndArray:
+ return "end-array";
+ case TokenType.EndDocument:
+ return "end-document";
+ default:
+ throw new InvalidOperationException("Token is of unknown type " + type);
+ }
+ }
+
+ public bool Equals(JsonToken other)
+ {
+ if (ReferenceEquals(other, null))
+ {
+ return false;
+ }
+ // Note use of other.numberValue.Equals rather than ==, so that NaN compares appropriately.
+ return other.type == type && other.stringValue == stringValue && other.numberValue.Equals(numberValue);
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/JsonTokenizer.cs b/csharp/src/Google.Protobuf/JsonTokenizer.cs
new file mode 100644
index 00000000..09a6d43b
--- /dev/null
+++ b/csharp/src/Google.Protobuf/JsonTokenizer.cs
@@ -0,0 +1,738 @@
+#region Copyright notice and license
+// 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.
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace Google.Protobuf
+{
+ /// <summary>
+ /// Simple but strict JSON tokenizer, rigidly following RFC 7159.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This tokenizer is stateful, and only returns "useful" tokens - names, values etc.
+ /// It does not create tokens for the separator between names and values, or for the comma
+ /// between values. It validates the token stream as it goes - so callers can assume that the
+ /// tokens it produces are appropriate. For example, it would never produce "start object, end array."
+ /// </para>
+ /// <para>Implementation details: the base class handles single token push-back and </para>
+ /// <para>Not thread-safe.</para>
+ /// </remarks>
+ internal abstract class JsonTokenizer
+ {
+ private JsonToken bufferedToken;
+
+ /// <summary>
+ /// Creates a tokenizer that reads from the given text reader.
+ /// </summary>
+ internal static JsonTokenizer FromTextReader(TextReader reader)
+ {
+ return new JsonTextTokenizer(reader);
+ }
+
+ /// <summary>
+ /// Creates a tokenizer that first replays the given list of tokens, then continues reading
+ /// from another tokenizer. Note that if the returned tokenizer is "pushed back", that does not push back
+ /// on the continuation tokenizer, or vice versa. Care should be taken when using this method - it was
+ /// created for the sake of Any parsing.
+ /// </summary>
+ internal static JsonTokenizer FromReplayedTokens(IList<JsonToken> tokens, JsonTokenizer continuation)
+ {
+ return new JsonReplayTokenizer(tokens, continuation);
+ }
+
+ /// <summary>
+ /// Returns the depth of the stack, purely in objects (not collections).
+ /// Informally, this is the number of remaining unclosed '{' characters we have.
+ /// </summary>
+ internal int ObjectDepth { get; private set; }
+
+ // TODO: Why do we allow a different token to be pushed back? It might be better to always remember the previous
+ // token returned, and allow a parameterless Rewind() method (which could only be called once, just like the current PushBack).
+ internal void PushBack(JsonToken token)
+ {
+ if (bufferedToken != null)
+ {
+ throw new InvalidOperationException("Can't push back twice");
+ }
+ bufferedToken = token;
+ if (token.Type == JsonToken.TokenType.StartObject)
+ {
+ ObjectDepth--;
+ }
+ else if (token.Type == JsonToken.TokenType.EndObject)
+ {
+ ObjectDepth++;
+ }
+ }
+
+ /// <summary>
+ /// Returns the next JSON token in the stream. An EndDocument token is returned to indicate the end of the stream,
+ /// after which point <c>Next()</c> should not be called again.
+ /// </summary>
+ /// <remarks>This implementation provides single-token buffering, and calls <see cref="NextImpl"/> if there is no buffered token.</remarks>
+ /// <returns>The next token in the stream. This is never null.</returns>
+ /// <exception cref="InvalidOperationException">This method is called after an EndDocument token has been returned</exception>
+ /// <exception cref="InvalidJsonException">The input text does not comply with RFC 7159</exception>
+ internal JsonToken Next()
+ {
+ JsonToken tokenToReturn;
+ if (bufferedToken != null)
+ {
+ tokenToReturn = bufferedToken;
+ bufferedToken = null;
+ }
+ else
+ {
+ tokenToReturn = NextImpl();
+ }
+ if (tokenToReturn.Type == JsonToken.TokenType.StartObject)
+ {
+ ObjectDepth++;
+ }
+ else if (tokenToReturn.Type == JsonToken.TokenType.EndObject)
+ {
+ ObjectDepth--;
+ }
+ return tokenToReturn;
+ }
+
+ /// <summary>
+ /// Returns the next JSON token in the stream, when requested by the base class. (The <see cref="Next"/> method delegates
+ /// to this if it doesn't have a buffered token.)
+ /// </summary>
+ /// <exception cref="InvalidOperationException">This method is called after an EndDocument token has been returned</exception>
+ /// <exception cref="InvalidJsonException">The input text does not comply with RFC 7159</exception>
+ protected abstract JsonToken NextImpl();
+
+ /// <summary>
+ /// Tokenizer which first exhausts a list of tokens, then consults another tokenizer.
+ /// </summary>
+ private class JsonReplayTokenizer : JsonTokenizer
+ {
+ private readonly IList<JsonToken> tokens;
+ private readonly JsonTokenizer nextTokenizer;
+ private int nextTokenIndex;
+
+ internal JsonReplayTokenizer(IList<JsonToken> tokens, JsonTokenizer nextTokenizer)
+ {
+ this.tokens = tokens;
+ this.nextTokenizer = nextTokenizer;
+ }
+
+ // FIXME: Object depth not maintained...
+ protected override JsonToken NextImpl()
+ {
+ if (nextTokenIndex >= tokens.Count)
+ {
+ return nextTokenizer.Next();
+ }
+ return tokens[nextTokenIndex++];
+ }
+ }
+
+ /// <summary>
+ /// Tokenizer which does all the *real* work of parsing JSON.
+ /// </summary>
+ private sealed class JsonTextTokenizer : JsonTokenizer
+ {
+ // The set of states in which a value is valid next token.
+ private static readonly State ValueStates = State.ArrayStart | State.ArrayAfterComma | State.ObjectAfterColon | State.StartOfDocument;
+
+ private readonly Stack<ContainerType> containerStack = new Stack<ContainerType>();
+ private readonly PushBackReader reader;
+ private State state;
+
+ internal JsonTextTokenizer(TextReader reader)
+ {
+ this.reader = new PushBackReader(reader);
+ state = State.StartOfDocument;
+ containerStack.Push(ContainerType.Document);
+ }
+
+ /// <remarks>
+ /// This method essentially just loops through characters skipping whitespace, validating and
+ /// changing state (e.g. from ObjectBeforeColon to ObjectAfterColon)
+ /// until it reaches something which will be a genuine token (e.g. a start object, or a value) at which point
+ /// it returns the token. Although the method is large, it would be relatively hard to break down further... most
+ /// of it is the large switch statement, which sometimes returns and sometimes doesn't.
+ /// </remarks>
+ protected override JsonToken NextImpl()
+ {
+ if (state == State.ReaderExhausted)
+ {
+ throw new InvalidOperationException("Next() called after end of document");
+ }
+ while (true)
+ {
+ var next = reader.Read();
+ if (next == null)
+ {
+ ValidateState(State.ExpectedEndOfDocument, "Unexpected end of document in state: ");
+ state = State.ReaderExhausted;
+ return JsonToken.EndDocument;
+ }
+ switch (next.Value)
+ {
+ // Skip whitespace between tokens
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ break;
+ case ':':
+ ValidateState(State.ObjectBeforeColon, "Invalid state to read a colon: ");
+ state = State.ObjectAfterColon;
+ break;
+ case ',':
+ ValidateState(State.ObjectAfterProperty | State.ArrayAfterValue, "Invalid state to read a colon: ");
+ state = state == State.ObjectAfterProperty ? State.ObjectAfterComma : State.ArrayAfterComma;
+ break;
+ case '"':
+ string stringValue = ReadString();
+ if ((state & (State.ObjectStart | State.ObjectAfterComma)) != 0)
+ {
+ state = State.ObjectBeforeColon;
+ return JsonToken.Name(stringValue);
+ }
+ else
+ {
+ ValidateAndModifyStateForValue("Invalid state to read a double quote: ");
+ return JsonToken.Value(stringValue);
+ }
+ case '{':
+ ValidateState(ValueStates, "Invalid state to read an open brace: ");
+ state = State.ObjectStart;
+ containerStack.Push(ContainerType.Object);
+ return JsonToken.StartObject;
+ case '}':
+ ValidateState(State.ObjectAfterProperty | State.ObjectStart, "Invalid state to read a close brace: ");
+ PopContainer();
+ return JsonToken.EndObject;
+ case '[':
+ ValidateState(ValueStates, "Invalid state to read an open square bracket: ");
+ state = State.ArrayStart;
+ containerStack.Push(ContainerType.Array);
+ return JsonToken.StartArray;
+ case ']':
+ ValidateState(State.ArrayAfterValue | State.ArrayStart, "Invalid state to read a close square bracket: ");
+ PopContainer();
+ return JsonToken.EndArray;
+ case 'n': // Start of null
+ ConsumeLiteral("null");
+ ValidateAndModifyStateForValue("Invalid state to read a null literal: ");
+ return JsonToken.Null;
+ case 't': // Start of true
+ ConsumeLiteral("true");
+ ValidateAndModifyStateForValue("Invalid state to read a true literal: ");
+ return JsonToken.True;
+ case 'f': // Start of false
+ ConsumeLiteral("false");
+ ValidateAndModifyStateForValue("Invalid state to read a false literal: ");
+ return JsonToken.False;
+ case '-': // Start of a number
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ double number = ReadNumber(next.Value);
+ ValidateAndModifyStateForValue("Invalid state to read a number token: ");
+ return JsonToken.Value(number);
+ default:
+ throw new InvalidJsonException("Invalid first character of token: " + next.Value);
+ }
+ }
+ }
+
+ private void ValidateState(State validStates, string errorPrefix)
+ {
+ if ((validStates & state) == 0)
+ {
+ throw reader.CreateException(errorPrefix + state);
+ }
+ }
+
+ /// <summary>
+ /// Reads a string token. It is assumed that the opening " has already been read.
+ /// </summary>
+ private string ReadString()
+ {
+ var value = new StringBuilder();
+ bool haveHighSurrogate = false;
+ while (true)
+ {
+ char c = reader.ReadOrFail("Unexpected end of text while reading string");
+ if (c < ' ')
+ {
+ throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in string literal: U+{0:x4}", (int) c));
+ }
+ if (c == '"')
+ {
+ if (haveHighSurrogate)
+ {
+ throw reader.CreateException("Invalid use of surrogate pair code units");
+ }
+ return value.ToString();
+ }
+ if (c == '\\')
+ {
+ c = ReadEscapedCharacter();
+ }
+ // TODO: Consider only allowing surrogate pairs that are either both escaped,
+ // or both not escaped. It would be a very odd text stream that contained a "lone" high surrogate
+ // followed by an escaped low surrogate or vice versa... and that couldn't even be represented in UTF-8.
+ if (haveHighSurrogate != char.IsLowSurrogate(c))
+ {
+ throw reader.CreateException("Invalid use of surrogate pair code units");
+ }
+ haveHighSurrogate = char.IsHighSurrogate(c);
+ value.Append(c);
+ }
+ }
+
+ /// <summary>
+ /// Reads an escaped character. It is assumed that the leading backslash has already been read.
+ /// </summary>
+ private char ReadEscapedCharacter()
+ {
+ char c = reader.ReadOrFail("Unexpected end of text while reading character escape sequence");
+ switch (c)
+ {
+ case 'n':
+ return '\n';
+ case '\\':
+ return '\\';
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'r':
+ return '\r';
+ case 't':
+ return '\t';
+ case '"':
+ return '"';
+ case '/':
+ return '/';
+ case 'u':
+ return ReadUnicodeEscape();
+ default:
+ throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int) c));
+ }
+ }
+
+ /// <summary>
+ /// Reads an escaped Unicode 4-nybble hex sequence. It is assumed that the leading \u has already been read.
+ /// </summary>
+ private char ReadUnicodeEscape()
+ {
+ int result = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ char c = reader.ReadOrFail("Unexpected end of text while reading Unicode escape sequence");
+ int nybble;
+ if (c >= '0' && c <= '9')
+ {
+ nybble = c - '0';
+ }
+ else if (c >= 'a' && c <= 'f')
+ {
+ nybble = c - 'a' + 10;
+ }
+ else if (c >= 'A' && c <= 'F')
+ {
+ nybble = c - 'A' + 10;
+ }
+ else
+ {
+ throw reader.CreateException(string.Format(CultureInfo.InvariantCulture, "Invalid character in character escape sequence: U+{0:x4}", (int) c));
+ }
+ result = (result << 4) + nybble;
+ }
+ return (char) result;
+ }
+
+ /// <summary>
+ /// Consumes a text-only literal, throwing an exception if the read text doesn't match it.
+ /// It is assumed that the first letter of the literal has already been read.
+ /// </summary>
+ private void ConsumeLiteral(string text)
+ {
+ for (int i = 1; i < text.Length; i++)
+ {
+ char? next = reader.Read();
+ if (next == null)
+ {
+ throw reader.CreateException("Unexpected end of text while reading literal token " + text);
+ }
+ if (next.Value != text[i])
+ {
+ throw reader.CreateException("Unexpected character while reading literal token " + text);
+ }
+ }
+ }
+
+ private double ReadNumber(char initialCharacter)
+ {
+ StringBuilder builder = new StringBuilder();
+ if (initialCharacter == '-')
+ {
+ builder.Append("-");
+ }
+ else
+ {
+ reader.PushBack(initialCharacter);
+ }
+ // Each method returns the character it read that doesn't belong in that part,
+ // so we know what to do next, including pushing the character back at the end.
+ // null is returned for "end of text".
+ char? next = ReadInt(builder);
+ if (next == '.')
+ {
+ next = ReadFrac(builder);
+ }
+ if (next == 'e' || next == 'E')
+ {
+ next = ReadExp(builder);
+ }
+ // If we read a character which wasn't part of the number, push it back so we can read it again
+ // to parse the next token.
+ if (next != null)
+ {
+ reader.PushBack(next.Value);
+ }
+
+ // TODO: What exception should we throw if the value can't be represented as a double?
+ try
+ {
+ return double.Parse(builder.ToString(),
+ NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent,
+ CultureInfo.InvariantCulture);
+ }
+ catch (OverflowException)
+ {
+ throw reader.CreateException("Numeric value out of range: " + builder);
+ }
+ }
+
+ private char? ReadInt(StringBuilder builder)
+ {
+ char first = reader.ReadOrFail("Invalid numeric literal");
+ if (first < '0' || first > '9')
+ {
+ throw reader.CreateException("Invalid numeric literal");
+ }
+ builder.Append(first);
+ int digitCount;
+ char? next = ConsumeDigits(builder, out digitCount);
+ if (first == '0' && digitCount != 0)
+ {
+ throw reader.CreateException("Invalid numeric literal: leading 0 for non-zero value.");
+ }
+ return next;
+ }
+
+ private char? ReadFrac(StringBuilder builder)
+ {
+ builder.Append('.'); // Already consumed this
+ int digitCount;
+ char? next = ConsumeDigits(builder, out digitCount);
+ if (digitCount == 0)
+ {
+ throw reader.CreateException("Invalid numeric literal: fraction with no trailing digits");
+ }
+ return next;
+ }
+
+ private char? ReadExp(StringBuilder builder)
+ {
+ builder.Append('E'); // Already consumed this (or 'e')
+ char? next = reader.Read();
+ if (next == null)
+ {
+ throw reader.CreateException("Invalid numeric literal: exponent with no trailing digits");
+ }
+ if (next == '-' || next == '+')
+ {
+ builder.Append(next.Value);
+ }
+ else
+ {
+ reader.PushBack(next.Value);
+ }
+ int digitCount;
+ next = ConsumeDigits(builder, out digitCount);
+ if (digitCount == 0)
+ {
+ throw reader.CreateException("Invalid numeric literal: exponent without value");
+ }
+ return next;
+ }
+
+ private char? ConsumeDigits(StringBuilder builder, out int count)
+ {
+ count = 0;
+ while (true)
+ {
+ char? next = reader.Read();
+ if (next == null || next.Value < '0' || next.Value > '9')
+ {
+ return next;
+ }
+ count++;
+ builder.Append(next.Value);
+ }
+ }
+
+ /// <summary>
+ /// Validates that we're in a valid state to read a value (using the given error prefix if necessary)
+ /// and changes the state to the appropriate one, e.g. ObjectAfterColon to ObjectAfterProperty.
+ /// </summary>
+ private void ValidateAndModifyStateForValue(string errorPrefix)
+ {
+ ValidateState(ValueStates, errorPrefix);
+ switch (state)
+ {
+ case State.StartOfDocument:
+ state = State.ExpectedEndOfDocument;
+ return;
+ case State.ObjectAfterColon:
+ state = State.ObjectAfterProperty;
+ return;
+ case State.ArrayStart:
+ case State.ArrayAfterComma:
+ state = State.ArrayAfterValue;
+ return;
+ default:
+ throw new InvalidOperationException("ValidateAndModifyStateForValue does not handle all value states (and should)");
+ }
+ }
+
+ /// <summary>
+ /// Pops the top-most container, and sets the state to the appropriate one for the end of a value
+ /// in the parent container.
+ /// </summary>
+ private void PopContainer()
+ {
+ containerStack.Pop();
+ var parent = containerStack.Peek();
+ switch (parent)
+ {
+ case ContainerType.Object:
+ state = State.ObjectAfterProperty;
+ break;
+ case ContainerType.Array:
+ state = State.ArrayAfterValue;
+ break;
+ case ContainerType.Document:
+ state = State.ExpectedEndOfDocument;
+ break;
+ default:
+ throw new InvalidOperationException("Unexpected container type: " + parent);
+ }
+ }
+
+ private enum ContainerType
+ {
+ Document, Object, Array
+ }
+
+ /// <summary>
+ /// Possible states of the tokenizer.
+ /// </summary>
+ /// <remarks>
+ /// <para>This is a flags enum purely so we can simply and efficiently represent a set of valid states
+ /// for checking.</para>
+ /// <para>
+ /// Each is documented with an example,
+ /// where ^ represents the current position within the text stream. The examples all use string values,
+ /// but could be any value, including nested objects/arrays.
+ /// The complete state of the tokenizer also includes a stack to indicate the contexts (arrays/objects).
+ /// Any additional notional state of "AfterValue" indicates that a value has been completed, at which
+ /// point there's an immediate transition to ExpectedEndOfDocument, ObjectAfterProperty or ArrayAfterValue.
+ /// </para>
+ /// <para>
+ /// These states were derived manually by reading RFC 7159 carefully.
+ /// </para>
+ /// </remarks>
+ [Flags]
+ private enum State
+ {
+ /// <summary>
+ /// ^ { "foo": "bar" }
+ /// Before the value in a document. Next states: ObjectStart, ArrayStart, "AfterValue"
+ /// </summary>
+ StartOfDocument = 1 << 0,
+ /// <summary>
+ /// { "foo": "bar" } ^
+ /// After the value in a document. Next states: ReaderExhausted
+ /// </summary>
+ ExpectedEndOfDocument = 1 << 1,
+ /// <summary>
+ /// { "foo": "bar" } ^ (and already read to the end of the reader)
+ /// Terminal state.
+ /// </summary>
+ ReaderExhausted = 1 << 2,
+ /// <summary>
+ /// { ^ "foo": "bar" }
+ /// Before the *first* property in an object.
+ /// Next states:
+ /// "AfterValue" (empty object)
+ /// ObjectBeforeColon (read a name)
+ /// </summary>
+ ObjectStart = 1 << 3,
+ /// <summary>
+ /// { "foo" ^ : "bar", "x": "y" }
+ /// Next state: ObjectAfterColon
+ /// </summary>
+ ObjectBeforeColon = 1 << 4,
+ /// <summary>
+ /// { "foo" : ^ "bar", "x": "y" }
+ /// Before any property other than the first in an object.
+ /// (Equivalently: after any property in an object)
+ /// Next states:
+ /// "AfterValue" (value is simple)
+ /// ObjectStart (value is object)
+ /// ArrayStart (value is array)
+ /// </summary>
+ ObjectAfterColon = 1 << 5,
+ /// <summary>
+ /// { "foo" : "bar" ^ , "x" : "y" }
+ /// At the end of a property, so expecting either a comma or end-of-object
+ /// Next states: ObjectAfterComma or "AfterValue"
+ /// </summary>
+ ObjectAfterProperty = 1 << 6,
+ /// <summary>
+ /// { "foo":"bar", ^ "x":"y" }
+ /// Read the comma after the previous property, so expecting another property.
+ /// This is like ObjectStart, but closing brace isn't valid here
+ /// Next state: ObjectBeforeColon.
+ /// </summary>
+ ObjectAfterComma = 1 << 7,
+ /// <summary>
+ /// [ ^ "foo", "bar" ]
+ /// Before the *first* value in an array.
+ /// Next states:
+ /// "AfterValue" (read a value)
+ /// "AfterValue" (end of array; will pop stack)
+ /// </summary>
+ ArrayStart = 1 << 8,
+ /// <summary>
+ /// [ "foo" ^ , "bar" ]
+ /// After any value in an array, so expecting either a comma or end-of-array
+ /// Next states: ArrayAfterComma or "AfterValue"
+ /// </summary>
+ ArrayAfterValue = 1 << 9,
+ /// <summary>
+ /// [ "foo", ^ "bar" ]
+ /// After a comma in an array, so there *must* be another value (simple or complex).
+ /// Next states: "AfterValue" (simple value), StartObject, StartArray
+ /// </summary>
+ ArrayAfterComma = 1 << 10
+ }
+
+ /// <summary>
+ /// Wrapper around a text reader allowing small amounts of buffering and location handling.
+ /// </summary>
+ private class PushBackReader
+ {
+ // TODO: Add locations for errors etc.
+
+ private readonly TextReader reader;
+
+ internal PushBackReader(TextReader reader)
+ {
+ // TODO: Wrap the reader in a BufferedReader?
+ this.reader = reader;
+ }
+
+ /// <summary>
+ /// The buffered next character, if we have one.
+ /// </summary>
+ private char? nextChar;
+
+ /// <summary>
+ /// Returns the next character in the stream, or null if we have reached the end.
+ /// </summary>
+ /// <returns></returns>
+ internal char? Read()
+ {
+ if (nextChar != null)
+ {
+ char? tmp = nextChar;
+ nextChar = null;
+ return tmp;
+ }
+ int next = reader.Read();
+ return next == -1 ? null : (char?) next;
+ }
+
+ internal char ReadOrFail(string messageOnFailure)
+ {
+ char? next = Read();
+ if (next == null)
+ {
+ throw CreateException(messageOnFailure);
+ }
+ return next.Value;
+ }
+
+ internal void PushBack(char c)
+ {
+ if (nextChar != null)
+ {
+ throw new InvalidOperationException("Cannot push back when already buffering a character");
+ }
+ nextChar = c;
+ }
+
+ /// <summary>
+ /// Creates a new exception appropriate for the current state of the reader.
+ /// </summary>
+ internal InvalidJsonException CreateException(string message)
+ {
+ // TODO: Keep track of and use the location.
+ return new InvalidJsonException(message);
+ }
+ }
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/MessageExtensions.cs b/csharp/src/Google.Protobuf/MessageExtensions.cs
index d2d057c0..047156c3 100644
--- a/csharp/src/Google.Protobuf/MessageExtensions.cs
+++ b/csharp/src/Google.Protobuf/MessageExtensions.cs
@@ -46,8 +46,8 @@ namespace Google.Protobuf
/// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeFrom(this IMessage message, byte[] data)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(data, "data");
CodedInputStream input = new CodedInputStream(data);
message.MergeFrom(input);
input.CheckReadEndOfStreamTag();
@@ -60,8 +60,8 @@ namespace Google.Protobuf
/// <param name="data">The data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeFrom(this IMessage message, ByteString data)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(data, "data");
CodedInputStream input = data.CreateCodedInput();
message.MergeFrom(input);
input.CheckReadEndOfStreamTag();
@@ -74,8 +74,8 @@ namespace Google.Protobuf
/// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeFrom(this IMessage message, Stream input)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(input, "input");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(input, "input");
CodedInputStream codedInput = new CodedInputStream(input);
message.MergeFrom(codedInput);
codedInput.CheckReadEndOfStreamTag();
@@ -92,8 +92,8 @@ namespace Google.Protobuf
/// <param name="input">Stream containing the data to merge, which must be protobuf-encoded binary data.</param>
public static void MergeDelimitedFrom(this IMessage message, Stream input)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(input, "input");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(input, "input");
int size = (int) CodedInputStream.ReadRawVarint32(input);
Stream limitedStream = new LimitedInputStream(input, size);
message.MergeFrom(limitedStream);
@@ -106,7 +106,7 @@ namespace Google.Protobuf
/// <returns>The message data as a byte array.</returns>
public static byte[] ToByteArray(this IMessage message)
{
- Preconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(message, "message");
byte[] result = new byte[message.CalculateSize()];
CodedOutputStream output = new CodedOutputStream(result);
message.WriteTo(output);
@@ -121,8 +121,8 @@ namespace Google.Protobuf
/// <param name="output">The stream to write to.</param>
public static void WriteTo(this IMessage message, Stream output)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(output, "output");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(output, "output");
CodedOutputStream codedOutput = new CodedOutputStream(output);
message.WriteTo(codedOutput);
codedOutput.Flush();
@@ -135,8 +135,8 @@ namespace Google.Protobuf
/// <param name="output">The output stream to write to.</param>
public static void WriteDelimitedTo(this IMessage message, Stream output)
{
- Preconditions.CheckNotNull(message, "message");
- Preconditions.CheckNotNull(output, "output");
+ ProtoPreconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(output, "output");
CodedOutputStream codedOutput = new CodedOutputStream(output);
codedOutput.WriteRawVarint32((uint)message.CalculateSize());
message.WriteTo(codedOutput);
@@ -150,7 +150,7 @@ namespace Google.Protobuf
/// <returns>The message data as a byte string.</returns>
public static ByteString ToByteString(this IMessage message)
{
- Preconditions.CheckNotNull(message, "message");
+ ProtoPreconditions.CheckNotNull(message, "message");
return ByteString.AttachBytes(message.ToByteArray());
}
}
diff --git a/csharp/src/Google.Protobuf/MessageParser.cs b/csharp/src/Google.Protobuf/MessageParser.cs
index 6a6f1017..8889638b 100644
--- a/csharp/src/Google.Protobuf/MessageParser.cs
+++ b/csharp/src/Google.Protobuf/MessageParser.cs
@@ -36,6 +36,109 @@ using System.IO;
namespace Google.Protobuf
{
/// <summary>
+ /// A general message parser, typically used by reflection-based code as all the methods
+ /// return simple <see cref="IMessage"/>.
+ /// </summary>
+ public class MessageParser
+ {
+ private Func<IMessage> factory;
+
+ internal MessageParser(Func<IMessage> factory)
+ {
+ this.factory = factory;
+ }
+
+ /// <summary>
+ /// Creates a template instance ready for population.
+ /// </summary>
+ /// <returns>An empty message.</returns>
+ internal IMessage CreateTemplate()
+ {
+ return factory();
+ }
+
+ /// <summary>
+ /// Parses a message from a byte array.
+ /// </summary>
+ /// <param name="data">The byte array containing the message. Must not be null.</param>
+ /// <returns>The newly parsed message.</returns>
+ public IMessage ParseFrom(byte[] data)
+ {
+ ProtoPreconditions.CheckNotNull(data, "data");
+ IMessage message = factory();
+ message.MergeFrom(data);
+ return message;
+ }
+
+ /// <summary>
+ /// Parses a message from the given byte string.
+ /// </summary>
+ /// <param name="data">The data to parse.</param>
+ /// <returns>The parsed message.</returns>
+ public IMessage ParseFrom(ByteString data)
+ {
+ ProtoPreconditions.CheckNotNull(data, "data");
+ IMessage message = factory();
+ message.MergeFrom(data);
+ return message;
+ }
+
+ /// <summary>
+ /// Parses a message from the given stream.
+ /// </summary>
+ /// <param name="input">The stream to parse.</param>
+ /// <returns>The parsed message.</returns>
+ public IMessage ParseFrom(Stream input)
+ {
+ IMessage message = factory();
+ message.MergeFrom(input);
+ return message;
+ }
+
+ /// <summary>
+ /// Parses a length-delimited message from the given stream.
+ /// </summary>
+ /// <remarks>
+ /// The stream is expected to contain a length and then the data. Only the amount of data
+ /// specified by the length will be consumed.
+ /// </remarks>
+ /// <param name="input">The stream to parse.</param>
+ /// <returns>The parsed message.</returns>
+ public IMessage ParseDelimitedFrom(Stream input)
+ {
+ IMessage message = factory();
+ message.MergeDelimitedFrom(input);
+ return message;
+ }
+
+ /// <summary>
+ /// Parses a message from the given coded input stream.
+ /// </summary>
+ /// <param name="input">The stream to parse.</param>
+ /// <returns>The parsed message.</returns>
+ public IMessage ParseFrom(CodedInputStream input)
+ {
+ IMessage message = factory();
+ message.MergeFrom(input);
+ return message;
+ }
+
+ /// <summary>
+ /// Parses a message from the given JSON.
+ /// </summary>
+ /// <param name="json">The JSON to parse.</param>
+ /// <returns>The parsed message.</returns>
+ /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception>
+ /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
+ public IMessage ParseJson(string json)
+ {
+ IMessage message = factory();
+ JsonParser.Default.Merge(message, json);
+ return message;
+ }
+ }
+
+ /// <summary>
/// A parser for a specific message type.
/// </summary>
/// <remarks>
@@ -51,8 +154,12 @@ namespace Google.Protobuf
/// </p>
/// </remarks>
/// <typeparam name="T">The type of message to be parsed.</typeparam>
- public sealed class MessageParser<T> where T : IMessage<T>
+ public sealed class MessageParser<T> : MessageParser where T : IMessage<T>
{
+ // Implementation note: all the methods here *could* just delegate up to the base class and cast the result.
+ // The current implementation avoids a virtual method call and a cast, which *may* be significant in some cases.
+ // Benchmarking work is required to measure the significance - but it's only a few lines of code in any case.
+ // The API wouldn't change anyway - just the implementation - so this work can be deferred.
private readonly Func<T> factory;
/// <summary>
@@ -63,7 +170,7 @@ namespace Google.Protobuf
/// to require a parameterless constructor: delegates are significantly faster to execute.
/// </remarks>
/// <param name="factory">Function to invoke when a new, empty message is required.</param>
- public MessageParser(Func<T> factory)
+ public MessageParser(Func<T> factory) : base(() => factory())
{
this.factory = factory;
}
@@ -72,7 +179,7 @@ namespace Google.Protobuf
/// Creates a template instance ready for population.
/// </summary>
/// <returns>An empty message.</returns>
- internal T CreateTemplate()
+ internal new T CreateTemplate()
{
return factory();
}
@@ -82,9 +189,9 @@ namespace Google.Protobuf
/// </summary>
/// <param name="data">The byte array containing the message. Must not be null.</param>
/// <returns>The newly parsed message.</returns>
- public T ParseFrom(byte[] data)
+ public new T ParseFrom(byte[] data)
{
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(data, "data");
T message = factory();
message.MergeFrom(data);
return message;
@@ -95,9 +202,9 @@ namespace Google.Protobuf
/// </summary>
/// <param name="data">The data to parse.</param>
/// <returns>The parsed message.</returns>
- public T ParseFrom(ByteString data)
+ public new T ParseFrom(ByteString data)
{
- Preconditions.CheckNotNull(data, "data");
+ ProtoPreconditions.CheckNotNull(data, "data");
T message = factory();
message.MergeFrom(data);
return message;
@@ -108,7 +215,7 @@ namespace Google.Protobuf
/// </summary>
/// <param name="input">The stream to parse.</param>
/// <returns>The parsed message.</returns>
- public T ParseFrom(Stream input)
+ public new T ParseFrom(Stream input)
{
T message = factory();
message.MergeFrom(input);
@@ -124,7 +231,7 @@ namespace Google.Protobuf
/// </remarks>
/// <param name="input">The stream to parse.</param>
/// <returns>The parsed message.</returns>
- public T ParseDelimitedFrom(Stream input)
+ public new T ParseDelimitedFrom(Stream input)
{
T message = factory();
message.MergeDelimitedFrom(input);
@@ -136,11 +243,25 @@ namespace Google.Protobuf
/// </summary>
/// <param name="input">The stream to parse.</param>
/// <returns>The parsed message.</returns>
- public T ParseFrom(CodedInputStream input)
+ public new T ParseFrom(CodedInputStream input)
{
T message = factory();
message.MergeFrom(input);
return message;
}
+
+ /// <summary>
+ /// Parses a message from the given JSON.
+ /// </summary>
+ /// <param name="json">The JSON to parse.</param>
+ /// <returns>The parsed message.</returns>
+ /// <exception cref="InvalidJsonException">The JSON does not comply with RFC 7159</exception>
+ /// <exception cref="InvalidProtocolBufferException">The JSON does not represent a Protocol Buffers message correctly</exception>
+ public new T ParseJson(string json)
+ {
+ T message = factory();
+ JsonParser.Default.Merge(message, json);
+ return message;
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs b/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
index 9a484ad6..0516f18e 100644
--- a/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
+++ b/csharp/src/Google.Protobuf/Properties/AssemblyInfo.cs
@@ -46,7 +46,10 @@ using System.Security;
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
+
+#if !NCRUNCH
[assembly: AllowPartiallyTrustedCallers]
+#endif
#if SIGNED
[assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=" +
@@ -61,4 +64,4 @@ using System.Security;
[assembly: AssemblyVersion("3.0.0.0")]
[assembly: AssemblyFileVersion("3.0.0.0")]
-[assembly: AssemblyInformationalVersion("3.0.0-alpha4")]
+[assembly: AssemblyInformationalVersion("3.0.0-beta3")]
diff --git a/csharp/src/Google.Protobuf/Preconditions.cs b/csharp/src/Google.Protobuf/ProtoPreconditions.cs
index 2db35ff6..abaeb9b4 100644
--- a/csharp/src/Google.Protobuf/Preconditions.cs
+++ b/csharp/src/Google.Protobuf/ProtoPreconditions.cs
@@ -35,9 +35,14 @@ using System;
namespace Google.Protobuf
{
/// <summary>
- /// Helper methods for throwing exceptions
+ /// Helper methods for throwing exceptions when preconditions are not met.
/// </summary>
- public static class Preconditions
+ /// <remarks>
+ /// This class is used internally and by generated code; it is not particularly
+ /// expected to be used from application code, although nothing prevents it
+ /// from being used that way.
+ /// </remarks>
+ public static class ProtoPreconditions
{
/// <summary>
/// Throws an ArgumentNullException if the given value is null, otherwise
diff --git a/csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
index 1e6a77ab..fa138dfe 100644
--- a/csharp/src/Google.Protobuf/Reflection/DescriptorProtoFile.cs
+++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Holder for reflection information generated from google/protobuf/descriptor.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- internal static partial class DescriptorProtoFile {
+ internal static partial class DescriptorReflection {
#region Descriptor
/// <summary>File descriptor for google/protobuf/descriptor.proto</summary>
@@ -20,7 +20,7 @@ namespace Google.Protobuf.Reflection {
}
private static pbr::FileDescriptor descriptor;
- static DescriptorProtoFile() {
+ static DescriptorReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90bxIPZ29vZ2xlLnBy",
@@ -50,112 +50,117 @@ namespace Google.Protobuf.Reflection {
"dG9idWYuRGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2USFQoNcmVzZXJ2",
"ZWRfbmFtZRgKIAMoCRosCg5FeHRlbnNpb25SYW5nZRINCgVzdGFydBgBIAEo",
"BRILCgNlbmQYAiABKAUaKwoNUmVzZXJ2ZWRSYW5nZRINCgVzdGFydBgBIAEo",
- "BRILCgNlbmQYAiABKAUiqQUKFEZpZWxkRGVzY3JpcHRvclByb3RvEgwKBG5h",
+ "BRILCgNlbmQYAiABKAUivAUKFEZpZWxkRGVzY3JpcHRvclByb3RvEgwKBG5h",
"bWUYASABKAkSDgoGbnVtYmVyGAMgASgFEjoKBWxhYmVsGAQgASgOMisuZ29v",
"Z2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxhYmVsEjgKBHR5",
"cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJv",
"dG8uVHlwZRIRCgl0eXBlX25hbWUYBiABKAkSEAoIZXh0ZW5kZWUYAiABKAkS",
- "FQoNZGVmYXVsdF92YWx1ZRgHIAEoCRITCgtvbmVvZl9pbmRleBgJIAEoBRIu",
- "CgdvcHRpb25zGAggASgLMh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9u",
- "cyK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIO",
- "CgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMy",
- "EAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQ",
- "RV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoM",
- "VFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMy",
- "EA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVf",
- "U0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIi",
- "QwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVFVSVJF",
- "RBACEhIKDkxBQkVMX1JFUEVBVEVEEAMiJAoUT25lb2ZEZXNjcmlwdG9yUHJv",
- "dG8SDAoEbmFtZRgBIAEoCSKMAQoTRW51bURlc2NyaXB0b3JQcm90bxIMCgRu",
- "YW1lGAEgASgJEjgKBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVu",
- "dW1WYWx1ZURlc2NyaXB0b3JQcm90bxItCgdvcHRpb25zGAMgASgLMhwuZ29v",
- "Z2xlLnByb3RvYnVmLkVudW1PcHRpb25zImwKGEVudW1WYWx1ZURlc2NyaXB0",
- "b3JQcm90bxIMCgRuYW1lGAEgASgJEg4KBm51bWJlchgCIAEoBRIyCgdvcHRp",
- "b25zGAMgASgLMiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMi",
- "kAEKFlNlcnZpY2VEZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRI2CgZt",
- "ZXRob2QYAiADKAsyJi5nb29nbGUucHJvdG9idWYuTWV0aG9kRGVzY3JpcHRv",
- "clByb3RvEjAKB29wdGlvbnMYAyABKAsyHy5nb29nbGUucHJvdG9idWYuU2Vy",
- "dmljZU9wdGlvbnMiwQEKFU1ldGhvZERlc2NyaXB0b3JQcm90bxIMCgRuYW1l",
- "GAEgASgJEhIKCmlucHV0X3R5cGUYAiABKAkSEwoLb3V0cHV0X3R5cGUYAyAB",
- "KAkSLwoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RP",
- "cHRpb25zEh8KEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlEh8KEHNl",
- "cnZlcl9zdHJlYW1pbmcYBiABKAg6BWZhbHNlIqoFCgtGaWxlT3B0aW9ucxIU",
- "CgxqYXZhX3BhY2thZ2UYASABKAkSHAoUamF2YV9vdXRlcl9jbGFzc25hbWUY",
- "CCABKAkSIgoTamF2YV9tdWx0aXBsZV9maWxlcxgKIAEoCDoFZmFsc2USLAod",
- "amF2YV9nZW5lcmF0ZV9lcXVhbHNfYW5kX2hhc2gYFCABKAg6BWZhbHNlEiUK",
- "FmphdmFfc3RyaW5nX2NoZWNrX3V0ZjgYGyABKAg6BWZhbHNlEkYKDG9wdGlt",
- "aXplX2ZvchgJIAEoDjIpLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucy5P",
- "cHRpbWl6ZU1vZGU6BVNQRUVEEhIKCmdvX3BhY2thZ2UYCyABKAkSIgoTY2Nf",
- "Z2VuZXJpY19zZXJ2aWNlcxgQIAEoCDoFZmFsc2USJAoVamF2YV9nZW5lcmlj",
- "X3NlcnZpY2VzGBEgASgIOgVmYWxzZRIiChNweV9nZW5lcmljX3NlcnZpY2Vz",
- "GBIgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGBcgASgIOgVmYWxzZRIfChBj",
- "Y19lbmFibGVfYXJlbmFzGB8gASgIOgVmYWxzZRIZChFvYmpjX2NsYXNzX3By",
- "ZWZpeBgkIAEoCRIYChBjc2hhcnBfbmFtZXNwYWNlGCUgASgJEicKH2phdmFu",
- "YW5vX3VzZV9kZXByZWNhdGVkX3BhY2thZ2UYJiABKAgSQwoUdW5pbnRlcnBy",
- "ZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJw",
- "cmV0ZWRPcHRpb24iOgoMT3B0aW1pemVNb2RlEgkKBVNQRUVEEAESDQoJQ09E",
- "RV9TSVpFEAISEAoMTElURV9SVU5USU1FEAMqCQjoBxCAgICAAiLmAQoOTWVz",
- "c2FnZU9wdGlvbnMSJgoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQYASABKAg6",
- "BWZhbHNlEi4KH25vX3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IYAiAB",
- "KAg6BWZhbHNlEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhEKCW1hcF9l",
- "bnRyeRgHIAEoCBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
- "b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIAC",
- "IpgDCgxGaWVsZE9wdGlvbnMSOgoFY3R5cGUYASABKA4yIy5nb29nbGUucHJv",
- "dG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkcSDgoGcGFja2VkGAIg",
- "ASgIEj8KBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9w",
- "dGlvbnMuSlNUeXBlOglKU19OT1JNQUwSEwoEbGF6eRgFIAEoCDoFZmFsc2US",
- "GQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEwoEd2VhaxgKIAEoCDoFZmFs",
- "c2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnBy",
- "b3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24iLwoFQ1R5cGUSCgoGU1RSSU5H",
- "EAASCAoEQ09SRBABEhAKDFNUUklOR19QSUVDRRACIjUKBkpTVHlwZRINCglK",
- "U19OT1JNQUwQABINCglKU19TVFJJTkcQARINCglKU19OVU1CRVIQAioJCOgH",
- "EICAgIACIo0BCgtFbnVtT3B0aW9ucxITCgthbGxvd19hbGlhcxgCIAEoCBIZ",
- "CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29w",
+ "FQoNZGVmYXVsdF92YWx1ZRgHIAEoCRITCgtvbmVvZl9pbmRleBgJIAEoBRIR",
+ "Cglqc29uX25hbWUYCiABKAkSLgoHb3B0aW9ucxgIIAEoCzIdLmdvb2dsZS5w",
+ "cm90b2J1Zi5GaWVsZE9wdGlvbnMitgIKBFR5cGUSDwoLVFlQRV9ET1VCTEUQ",
+ "ARIOCgpUWVBFX0ZMT0FUEAISDgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlO",
+ "VDY0EAQSDgoKVFlQRV9JTlQzMhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZ",
+ "UEVfRklYRUQzMhAHEg0KCVRZUEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkS",
+ "DgoKVFlQRV9HUk9VUBAKEhAKDFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllU",
+ "RVMQDBIPCgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVf",
+ "U0ZJWEVEMzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQ",
+ "ERIPCgtUWVBFX1NJTlQ2NBASIkMKBUxhYmVsEhIKDkxBQkVMX09QVElPTkFM",
+ "EAESEgoOTEFCRUxfUkVRVUlSRUQQAhISCg5MQUJFTF9SRVBFQVRFRBADIiQK",
+ "FE9uZW9mRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkijAEKE0VudW1E",
+ "ZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRI4CgV2YWx1ZRgCIAMoCzIp",
+ "Lmdvb2dsZS5wcm90b2J1Zi5FbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SLQoH",
+ "b3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucyJs",
+ "ChhFbnVtVmFsdWVEZXNjcmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRIOCgZu",
+ "dW1iZXIYAiABKAUSMgoHb3B0aW9ucxgDIAEoCzIhLmdvb2dsZS5wcm90b2J1",
+ "Zi5FbnVtVmFsdWVPcHRpb25zIpABChZTZXJ2aWNlRGVzY3JpcHRvclByb3Rv",
+ "EgwKBG5hbWUYASABKAkSNgoGbWV0aG9kGAIgAygLMiYuZ29vZ2xlLnByb3Rv",
+ "YnVmLk1ldGhvZERlc2NyaXB0b3JQcm90bxIwCgdvcHRpb25zGAMgASgLMh8u",
+ "Z29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zIsEBChVNZXRob2REZXNj",
+ "cmlwdG9yUHJvdG8SDAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJ",
+ "EhMKC291dHB1dF90eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29n",
+ "bGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5n",
+ "GAUgASgIOgVmYWxzZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxz",
+ "ZSKHBQoLRmlsZU9wdGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGph",
+ "dmFfb3V0ZXJfY2xhc3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmls",
+ "ZXMYCiABKAg6BWZhbHNlEiwKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9o",
+ "YXNoGBQgASgIOgVmYWxzZRIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsg",
+ "ASgIOgVmYWxzZRJGCgxvcHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJv",
+ "dG9idWYuRmlsZU9wdGlvbnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19w",
+ "YWNrYWdlGAsgASgJEiIKE2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZh",
+ "bHNlEiQKFWphdmFfZ2VuZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoT",
+ "cHlfZ2VuZXJpY19zZXJ2aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRl",
+ "ZBgXIAEoCDoFZmFsc2USHwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFs",
+ "c2USGQoRb2JqY19jbGFzc19wcmVmaXgYJCABKAkSGAoQY3NoYXJwX25hbWVz",
+ "cGFjZRglIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
+ "b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRpbWl6",
+ "ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JVTlRJ",
+ "TUUQAyoJCOgHEICAgIACSgQIJhAnIuYBCg5NZXNzYWdlT3B0aW9ucxImChdt",
+ "ZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9fc3Rh",
+ "bmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoKZGVw",
+ "cmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMKFHVu",
+ "aW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5V",
+ "bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAMKDEZpZWxkT3B0aW9u",
+ "cxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlv",
+ "bnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoGanN0eXBlGAYg",
+ "ASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5KU1R5cGU6CUpT",
+ "X05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMg",
+ "ASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1bmludGVycHJl",
+ "dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
+ "ZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoM",
+ "U1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpT",
+ "X1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIijQEKC0VudW1P",
+ "cHRpb25zEhMKC2FsbG93X2FsaWFzGAIgASgIEhkKCmRlcHJlY2F0ZWQYAyAB",
+ "KAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv",
+ "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIi",
+ "fQoQRW51bVZhbHVlT3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxz",
+ "ZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJv",
+ "dG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNlcnZp",
+ "Y2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50",
+ "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu",
+ "dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiegoNTWV0aG9kT3B0aW9ucxIZ",
+ "CgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29w",
"dGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9w",
- "dGlvbioJCOgHEICAgIACIn0KEEVudW1WYWx1ZU9wdGlvbnMSGQoKZGVwcmVj",
- "YXRlZBgBIAEoCDoFZmFsc2USQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcg",
- "AygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjo",
- "BxCAgICAAiJ7Cg5TZXJ2aWNlT3B0aW9ucxIZCgpkZXByZWNhdGVkGCEgASgI",
- "OgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29n",
- "bGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACInoK",
- "DU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USQwoU",
- "dW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVm",
- "LlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKeAgoTVW5pbnRlcnBy",
- "ZXRlZE9wdGlvbhI7CgRuYW1lGAIgAygLMi0uZ29vZ2xlLnByb3RvYnVmLlVu",
- "aW50ZXJwcmV0ZWRPcHRpb24uTmFtZVBhcnQSGAoQaWRlbnRpZmllcl92YWx1",
- "ZRgDIAEoCRIaChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKAQSGgoSbmVnYXRp",
- "dmVfaW50X3ZhbHVlGAUgASgDEhQKDGRvdWJsZV92YWx1ZRgGIAEoARIUCgxz",
- "dHJpbmdfdmFsdWUYByABKAwSFwoPYWdncmVnYXRlX3ZhbHVlGAggASgJGjMK",
- "CE5hbWVQYXJ0EhEKCW5hbWVfcGFydBgBIAIoCRIUCgxpc19leHRlbnNpb24Y",
- "AiACKAgi1QEKDlNvdXJjZUNvZGVJbmZvEjoKCGxvY2F0aW9uGAEgAygLMigu",
- "Z29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uGoYBCghM",
- "b2NhdGlvbhIQCgRwYXRoGAEgAygFQgIQARIQCgRzcGFuGAIgAygFQgIQARIY",
- "ChBsZWFkaW5nX2NvbW1lbnRzGAMgASgJEhkKEXRyYWlsaW5nX2NvbW1lbnRz",
- "GAQgASgJEiEKGWxlYWRpbmdfZGV0YWNoZWRfY29tbWVudHMYBiADKAlCWAoT",
- "Y29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gBWgpkZXNj",
- "cmlwdG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVmLlJlZmxlY3Rpb24="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+ "dGlvbioJCOgHEICAgIACIp4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5h",
+ "bWUYAiADKAsyLS5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlv",
+ "bi5OYW1lUGFydBIYChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0",
+ "aXZlX2ludF92YWx1ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSAB",
+ "KAMSFAoMZG91YmxlX3ZhbHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEo",
+ "DBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFt",
+ "ZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291cmNl",
+ "Q29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYu",
+ "U291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBhdGgY",
+ "ASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29tbWVu",
+ "dHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVhZGlu",
+ "Z19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29kZUlu",
+ "Zm8SQQoKYW5ub3RhdGlvbhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5HZW5l",
+ "cmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoEcGF0",
+ "aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4YAyAB",
+ "KAUSCwoDZW5kGAQgASgFQlgKE2NvbS5nb29nbGUucHJvdG9idWZCEERlc2Ny",
+ "aXB0b3JQcm90b3NIAVoKZGVzY3JpcHRvcqICA0dQQqoCGkdvb2dsZS5Qcm90",
+ "b2J1Zi5SZWZsZWN0aW9u"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), new[]{ "File" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), new[]{ "Start", "End" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), new[]{ "Start", "End" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), new[]{ "Name" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), new[]{ "Name", "Value", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), new[]{ "Name", "Number", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), new[]{ "Name", "Method", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "JavananoUseDeprecatedPackage", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), new[]{ "NamePart_", "IsExtension" }, null, null, null)}),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), new[]{ "Location" }, null, null, new pbr::GeneratedCodeInfo[] { new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null)})
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorSet), global::Google.Protobuf.Reflection.FileDescriptorSet.Parser, new[]{ "File" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileDescriptorProto), global::Google.Protobuf.Reflection.FileDescriptorProto.Parser, new[]{ "Name", "Package", "Dependency", "PublicDependency", "WeakDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto), global::Google.Protobuf.Reflection.DescriptorProto.Parser, new[]{ "Name", "Field", "Extension", "NestedType", "EnumType", "ExtensionRange", "OneofDecl", "Options", "ReservedRange", "ReservedName" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ExtensionRange.Parser, new[]{ "Start", "End" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange), global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser, new[]{ "Start", "End" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto), global::Google.Protobuf.Reflection.FieldDescriptorProto.Parser, new[]{ "Name", "Number", "Label", "Type", "TypeName", "Extendee", "DefaultValue", "OneofIndex", "JsonName", "Options" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type), typeof(global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofDescriptorProto), global::Google.Protobuf.Reflection.OneofDescriptorProto.Parser, new[]{ "Name" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumDescriptorProto), global::Google.Protobuf.Reflection.EnumDescriptorProto.Parser, new[]{ "Name", "Value", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueDescriptorProto), global::Google.Protobuf.Reflection.EnumValueDescriptorProto.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceDescriptorProto), global::Google.Protobuf.Reflection.ServiceDescriptorProto.Parser, new[]{ "Name", "Method", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodDescriptorProto), global::Google.Protobuf.Reflection.MethodDescriptorProto.Parser, new[]{ "Name", "InputType", "OutputType", "Options", "ClientStreaming", "ServerStreaming" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FileOptions), global::Google.Protobuf.Reflection.FileOptions.Parser, new[]{ "JavaPackage", "JavaOuterClassname", "JavaMultipleFiles", "JavaGenerateEqualsAndHash", "JavaStringCheckUtf8", "OptimizeFor", "GoPackage", "CcGenericServices", "JavaGenericServices", "PyGenericServices", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MessageOptions), global::Google.Protobuf.Reflection.MessageOptions.Parser, new[]{ "MessageSetWireFormat", "NoStandardDescriptorAccessor", "Deprecated", "MapEntry", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions), global::Google.Protobuf.Reflection.FieldOptions.Parser, new[]{ "Ctype", "Packed", "Jstype", "Lazy", "Deprecated", "Weak", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "UninterpretedOption" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption), global::Google.Protobuf.Reflection.UninterpretedOption.Parser, new[]{ "Name", "IdentifierValue", "PositiveIntValue", "NegativeIntValue", "DoubleValue", "StringValue", "AggregateValue" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart), global::Google.Protobuf.Reflection.UninterpretedOption.Types.NamePart.Parser, new[]{ "NamePart_", "IsExtension" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo), global::Google.Protobuf.Reflection.SourceCodeInfo.Parser, new[]{ "Location" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location), global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location.Parser, new[]{ "Path", "Span", "LeadingComments", "TrailingComments", "LeadingDetachedComments" }, null, null, null)}),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Parser, new[]{ "Annotation" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation), global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser, new[]{ "Path", "SourceFile", "Begin", "End" }, null, null, null)})
}));
}
#endregion
@@ -172,7 +177,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<FileDescriptorSet> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -224,7 +229,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -270,7 +275,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<FileDescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -311,7 +316,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -324,7 +329,7 @@ namespace Google.Protobuf.Reflection {
public string Package {
get { return package_; }
set {
- package_ = pb::Preconditions.CheckNotNull(value, "value");
+ package_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -440,7 +445,7 @@ namespace Google.Protobuf.Reflection {
public string Syntax {
get { return syntax_; }
set {
- syntax_ = pb::Preconditions.CheckNotNull(value, "value");
+ syntax_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -488,7 +493,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -660,7 +665,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<DescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -696,7 +701,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -826,7 +831,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1020,7 +1025,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1161,7 +1166,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1233,7 +1238,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<FieldDescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[3]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1255,6 +1260,7 @@ namespace Google.Protobuf.Reflection {
extendee_ = other.extendee_;
defaultValue_ = other.defaultValue_;
oneofIndex_ = other.oneofIndex_;
+ jsonName_ = other.jsonName_;
Options = other.options_ != null ? other.Options.Clone() : null;
}
@@ -1268,7 +1274,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1284,7 +1290,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "label" field.</summary>
public const int LabelFieldNumber = 4;
- private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_ = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL;
+ private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label label_ = 0;
public global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label Label {
get { return label_; }
set {
@@ -1294,7 +1300,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "type" field.</summary>
public const int TypeFieldNumber = 5;
- private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_ = global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE;
+ private global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type type_ = 0;
/// <summary>
/// If type_name is set, this need not be set. If both this and type_name
/// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
@@ -1319,7 +1325,7 @@ namespace Google.Protobuf.Reflection {
public string TypeName {
get { return typeName_; }
set {
- typeName_ = pb::Preconditions.CheckNotNull(value, "value");
+ typeName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1333,7 +1339,7 @@ namespace Google.Protobuf.Reflection {
public string Extendee {
get { return extendee_; }
set {
- extendee_ = pb::Preconditions.CheckNotNull(value, "value");
+ extendee_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1350,7 +1356,7 @@ namespace Google.Protobuf.Reflection {
public string DefaultValue {
get { return defaultValue_; }
set {
- defaultValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ defaultValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1368,6 +1374,22 @@ namespace Google.Protobuf.Reflection {
}
}
+ /// <summary>Field number for the "json_name" field.</summary>
+ public const int JsonNameFieldNumber = 10;
+ private string jsonName_ = "";
+ /// <summary>
+ /// JSON name of this field. The value is set by protocol compiler. If the
+ /// user has set a "json_name" option on this field, that option's value
+ /// will be used. Otherwise, it's deduced from the field's name by converting
+ /// it to camelCase.
+ /// </summary>
+ public string JsonName {
+ get { return jsonName_; }
+ set {
+ jsonName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
/// <summary>Field number for the "options" field.</summary>
public const int OptionsFieldNumber = 8;
private global::Google.Protobuf.Reflection.FieldOptions options_;
@@ -1397,6 +1419,7 @@ namespace Google.Protobuf.Reflection {
if (Extendee != other.Extendee) return false;
if (DefaultValue != other.DefaultValue) return false;
if (OneofIndex != other.OneofIndex) return false;
+ if (JsonName != other.JsonName) return false;
if (!object.Equals(Options, other.Options)) return false;
return true;
}
@@ -1405,18 +1428,19 @@ namespace Google.Protobuf.Reflection {
int hash = 1;
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (Number != 0) hash ^= Number.GetHashCode();
- if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) hash ^= Label.GetHashCode();
- if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) hash ^= Type.GetHashCode();
+ if (Label != 0) hash ^= Label.GetHashCode();
+ if (Type != 0) hash ^= Type.GetHashCode();
if (TypeName.Length != 0) hash ^= TypeName.GetHashCode();
if (Extendee.Length != 0) hash ^= Extendee.GetHashCode();
if (DefaultValue.Length != 0) hash ^= DefaultValue.GetHashCode();
if (OneofIndex != 0) hash ^= OneofIndex.GetHashCode();
+ if (JsonName.Length != 0) hash ^= JsonName.GetHashCode();
if (options_ != null) hash ^= Options.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1432,11 +1456,11 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(24);
output.WriteInt32(Number);
}
- if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
+ if (Label != 0) {
output.WriteRawTag(32);
output.WriteEnum((int) Label);
}
- if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
+ if (Type != 0) {
output.WriteRawTag(40);
output.WriteEnum((int) Type);
}
@@ -1456,6 +1480,10 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(72);
output.WriteInt32(OneofIndex);
}
+ if (JsonName.Length != 0) {
+ output.WriteRawTag(82);
+ output.WriteString(JsonName);
+ }
}
public int CalculateSize() {
@@ -1466,10 +1494,10 @@ namespace Google.Protobuf.Reflection {
if (Number != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
}
- if (Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
+ if (Label != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Label);
}
- if (Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
+ if (Type != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Type);
}
if (TypeName.Length != 0) {
@@ -1484,6 +1512,9 @@ namespace Google.Protobuf.Reflection {
if (OneofIndex != 0) {
size += 1 + pb::CodedOutputStream.ComputeInt32Size(OneofIndex);
}
+ if (JsonName.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonName);
+ }
if (options_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
}
@@ -1500,10 +1531,10 @@ namespace Google.Protobuf.Reflection {
if (other.Number != 0) {
Number = other.Number;
}
- if (other.Label != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label.LABEL_OPTIONAL) {
+ if (other.Label != 0) {
Label = other.Label;
}
- if (other.Type != global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type.TYPE_DOUBLE) {
+ if (other.Type != 0) {
Type = other.Type;
}
if (other.TypeName.Length != 0) {
@@ -1518,6 +1549,9 @@ namespace Google.Protobuf.Reflection {
if (other.OneofIndex != 0) {
OneofIndex = other.OneofIndex;
}
+ if (other.JsonName.Length != 0) {
+ JsonName = other.JsonName;
+ }
if (other.options_ != null) {
if (options_ == null) {
options_ = new global::Google.Protobuf.Reflection.FieldOptions();
@@ -1572,6 +1606,10 @@ namespace Google.Protobuf.Reflection {
OneofIndex = input.ReadInt32();
break;
}
+ case 82: {
+ JsonName = input.ReadString();
+ break;
+ }
}
}
}
@@ -1585,59 +1623,59 @@ namespace Google.Protobuf.Reflection {
/// 0 is reserved for errors.
/// Order is weird for historical reasons.
/// </summary>
- TYPE_DOUBLE = 1,
- TYPE_FLOAT = 2,
+ [pbr::OriginalName("TYPE_DOUBLE")] Double = 1,
+ [pbr::OriginalName("TYPE_FLOAT")] Float = 2,
/// <summary>
/// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
/// negative values are likely.
/// </summary>
- TYPE_INT64 = 3,
- TYPE_UINT64 = 4,
+ [pbr::OriginalName("TYPE_INT64")] Int64 = 3,
+ [pbr::OriginalName("TYPE_UINT64")] Uint64 = 4,
/// <summary>
/// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
/// negative values are likely.
/// </summary>
- TYPE_INT32 = 5,
- TYPE_FIXED64 = 6,
- TYPE_FIXED32 = 7,
- TYPE_BOOL = 8,
- TYPE_STRING = 9,
+ [pbr::OriginalName("TYPE_INT32")] Int32 = 5,
+ [pbr::OriginalName("TYPE_FIXED64")] Fixed64 = 6,
+ [pbr::OriginalName("TYPE_FIXED32")] Fixed32 = 7,
+ [pbr::OriginalName("TYPE_BOOL")] Bool = 8,
+ [pbr::OriginalName("TYPE_STRING")] String = 9,
/// <summary>
/// Tag-delimited aggregate.
/// </summary>
- TYPE_GROUP = 10,
+ [pbr::OriginalName("TYPE_GROUP")] Group = 10,
/// <summary>
/// Length-delimited aggregate.
/// </summary>
- TYPE_MESSAGE = 11,
+ [pbr::OriginalName("TYPE_MESSAGE")] Message = 11,
/// <summary>
/// New in version 2.
/// </summary>
- TYPE_BYTES = 12,
- TYPE_UINT32 = 13,
- TYPE_ENUM = 14,
- TYPE_SFIXED32 = 15,
- TYPE_SFIXED64 = 16,
+ [pbr::OriginalName("TYPE_BYTES")] Bytes = 12,
+ [pbr::OriginalName("TYPE_UINT32")] Uint32 = 13,
+ [pbr::OriginalName("TYPE_ENUM")] Enum = 14,
+ [pbr::OriginalName("TYPE_SFIXED32")] Sfixed32 = 15,
+ [pbr::OriginalName("TYPE_SFIXED64")] Sfixed64 = 16,
/// <summary>
/// Uses ZigZag encoding.
/// </summary>
- TYPE_SINT32 = 17,
+ [pbr::OriginalName("TYPE_SINT32")] Sint32 = 17,
/// <summary>
/// Uses ZigZag encoding.
/// </summary>
- TYPE_SINT64 = 18,
+ [pbr::OriginalName("TYPE_SINT64")] Sint64 = 18,
}
internal enum Label {
/// <summary>
/// 0 is reserved for errors
/// </summary>
- LABEL_OPTIONAL = 1,
- LABEL_REQUIRED = 2,
+ [pbr::OriginalName("LABEL_OPTIONAL")] Optional = 1,
+ [pbr::OriginalName("LABEL_REQUIRED")] Required = 2,
/// <summary>
/// TODO(sanjay): Should we add LABEL_MAP?
/// </summary>
- LABEL_REPEATED = 3,
+ [pbr::OriginalName("LABEL_REPEATED")] Repeated = 3,
}
}
@@ -1654,7 +1692,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<OneofDescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[4]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[4]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1681,7 +1719,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1707,7 +1745,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1760,7 +1798,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<EnumDescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[5]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[5]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1789,7 +1827,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1838,7 +1876,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1918,7 +1956,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<EnumValueDescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[6]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[6]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1947,7 +1985,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1997,7 +2035,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2084,7 +2122,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<ServiceDescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[7]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[7]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2113,7 +2151,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2162,7 +2200,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2242,7 +2280,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<MethodDescriptorProto> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[8]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[8]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2274,7 +2312,7 @@ namespace Google.Protobuf.Reflection {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2288,7 +2326,7 @@ namespace Google.Protobuf.Reflection {
public string InputType {
get { return inputType_; }
set {
- inputType_ = pb::Preconditions.CheckNotNull(value, "value");
+ inputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2298,7 +2336,7 @@ namespace Google.Protobuf.Reflection {
public string OutputType {
get { return outputType_; }
set {
- outputType_ = pb::Preconditions.CheckNotNull(value, "value");
+ outputType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2370,7 +2408,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2496,7 +2534,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<FileOptions> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[9]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[9]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -2524,7 +2562,6 @@ namespace Google.Protobuf.Reflection {
ccEnableArenas_ = other.ccEnableArenas_;
objcClassPrefix_ = other.objcClassPrefix_;
csharpNamespace_ = other.csharpNamespace_;
- javananoUseDeprecatedPackage_ = other.javananoUseDeprecatedPackage_;
uninterpretedOption_ = other.uninterpretedOption_.Clone();
}
@@ -2544,7 +2581,7 @@ namespace Google.Protobuf.Reflection {
public string JavaPackage {
get { return javaPackage_; }
set {
- javaPackage_ = pb::Preconditions.CheckNotNull(value, "value");
+ javaPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2561,7 +2598,7 @@ namespace Google.Protobuf.Reflection {
public string JavaOuterClassname {
get { return javaOuterClassname_; }
set {
- javaOuterClassname_ = pb::Preconditions.CheckNotNull(value, "value");
+ javaOuterClassname_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2627,7 +2664,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "optimize_for" field.</summary>
public const int OptimizeForFieldNumber = 9;
- private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_ = global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED;
+ private global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode optimizeFor_ = 0;
public global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode OptimizeFor {
get { return optimizeFor_; }
set {
@@ -2648,7 +2685,7 @@ namespace Google.Protobuf.Reflection {
public string GoPackage {
get { return goPackage_; }
set {
- goPackage_ = pb::Preconditions.CheckNotNull(value, "value");
+ goPackage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2661,6 +2698,7 @@ namespace Google.Protobuf.Reflection {
/// main code generators in each language (without additional plugins).
/// Generic services were the only kind of service generation supported by
/// early versions of google.protobuf.
+ ///
/// Generic services are now considered deprecated in favor of using plugins
/// that generate code specific to your particular RPC system. Therefore,
/// these default to false. Old code which depends on generic services should
@@ -2733,7 +2771,7 @@ namespace Google.Protobuf.Reflection {
public string ObjcClassPrefix {
get { return objcClassPrefix_; }
set {
- objcClassPrefix_ = pb::Preconditions.CheckNotNull(value, "value");
+ objcClassPrefix_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2746,21 +2784,7 @@ namespace Google.Protobuf.Reflection {
public string CsharpNamespace {
get { return csharpNamespace_; }
set {
- csharpNamespace_ = pb::Preconditions.CheckNotNull(value, "value");
- }
- }
-
- /// <summary>Field number for the "javanano_use_deprecated_package" field.</summary>
- public const int JavananoUseDeprecatedPackageFieldNumber = 38;
- private bool javananoUseDeprecatedPackage_;
- /// <summary>
- /// Whether the nano proto compiler should generate in the deprecated non-nano
- /// suffixed package.
- /// </summary>
- public bool JavananoUseDeprecatedPackage {
- get { return javananoUseDeprecatedPackage_; }
- set {
- javananoUseDeprecatedPackage_ = value;
+ csharpNamespace_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -2801,7 +2825,6 @@ namespace Google.Protobuf.Reflection {
if (CcEnableArenas != other.CcEnableArenas) return false;
if (ObjcClassPrefix != other.ObjcClassPrefix) return false;
if (CsharpNamespace != other.CsharpNamespace) return false;
- if (JavananoUseDeprecatedPackage != other.JavananoUseDeprecatedPackage) return false;
if(!uninterpretedOption_.Equals(other.uninterpretedOption_)) return false;
return true;
}
@@ -2813,7 +2836,7 @@ namespace Google.Protobuf.Reflection {
if (JavaMultipleFiles != false) hash ^= JavaMultipleFiles.GetHashCode();
if (JavaGenerateEqualsAndHash != false) hash ^= JavaGenerateEqualsAndHash.GetHashCode();
if (JavaStringCheckUtf8 != false) hash ^= JavaStringCheckUtf8.GetHashCode();
- if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) hash ^= OptimizeFor.GetHashCode();
+ if (OptimizeFor != 0) hash ^= OptimizeFor.GetHashCode();
if (GoPackage.Length != 0) hash ^= GoPackage.GetHashCode();
if (CcGenericServices != false) hash ^= CcGenericServices.GetHashCode();
if (JavaGenericServices != false) hash ^= JavaGenericServices.GetHashCode();
@@ -2822,13 +2845,12 @@ namespace Google.Protobuf.Reflection {
if (CcEnableArenas != false) hash ^= CcEnableArenas.GetHashCode();
if (ObjcClassPrefix.Length != 0) hash ^= ObjcClassPrefix.GetHashCode();
if (CsharpNamespace.Length != 0) hash ^= CsharpNamespace.GetHashCode();
- if (JavananoUseDeprecatedPackage != false) hash ^= JavananoUseDeprecatedPackage.GetHashCode();
hash ^= uninterpretedOption_.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -2840,7 +2862,7 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(66);
output.WriteString(JavaOuterClassname);
}
- if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
+ if (OptimizeFor != 0) {
output.WriteRawTag(72);
output.WriteEnum((int) OptimizeFor);
}
@@ -2888,10 +2910,6 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(170, 2);
output.WriteString(CsharpNamespace);
}
- if (JavananoUseDeprecatedPackage != false) {
- output.WriteRawTag(176, 2);
- output.WriteBool(JavananoUseDeprecatedPackage);
- }
uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
}
@@ -2912,7 +2930,7 @@ namespace Google.Protobuf.Reflection {
if (JavaStringCheckUtf8 != false) {
size += 2 + 1;
}
- if (OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
+ if (OptimizeFor != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) OptimizeFor);
}
if (GoPackage.Length != 0) {
@@ -2939,9 +2957,6 @@ namespace Google.Protobuf.Reflection {
if (CsharpNamespace.Length != 0) {
size += 2 + pb::CodedOutputStream.ComputeStringSize(CsharpNamespace);
}
- if (JavananoUseDeprecatedPackage != false) {
- size += 2 + 1;
- }
size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
return size;
}
@@ -2965,7 +2980,7 @@ namespace Google.Protobuf.Reflection {
if (other.JavaStringCheckUtf8 != false) {
JavaStringCheckUtf8 = other.JavaStringCheckUtf8;
}
- if (other.OptimizeFor != global::Google.Protobuf.Reflection.FileOptions.Types.OptimizeMode.SPEED) {
+ if (other.OptimizeFor != 0) {
OptimizeFor = other.OptimizeFor;
}
if (other.GoPackage.Length != 0) {
@@ -2992,9 +3007,6 @@ namespace Google.Protobuf.Reflection {
if (other.CsharpNamespace.Length != 0) {
CsharpNamespace = other.CsharpNamespace;
}
- if (other.JavananoUseDeprecatedPackage != false) {
- JavananoUseDeprecatedPackage = other.JavananoUseDeprecatedPackage;
- }
uninterpretedOption_.Add(other.uninterpretedOption_);
}
@@ -3061,10 +3073,6 @@ namespace Google.Protobuf.Reflection {
CsharpNamespace = input.ReadString();
break;
}
- case 304: {
- JavananoUseDeprecatedPackage = input.ReadBool();
- break;
- }
case 7994: {
uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
break;
@@ -3084,15 +3092,15 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Generate complete code for parsing, serialization,
/// </summary>
- SPEED = 1,
+ [pbr::OriginalName("SPEED")] Speed = 1,
/// <summary>
/// etc.
/// </summary>
- CODE_SIZE = 2,
+ [pbr::OriginalName("CODE_SIZE")] CodeSize = 2,
/// <summary>
/// Generate code using MessageLite and the lite runtime.
/// </summary>
- LITE_RUNTIME = 3,
+ [pbr::OriginalName("LITE_RUNTIME")] LiteRuntime = 3,
}
}
@@ -3106,7 +3114,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<MessageOptions> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[10]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[10]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3139,6 +3147,7 @@ namespace Google.Protobuf.Reflection {
/// This is provided for backwards-compatibility with the MessageSet wire
/// format. You should not use this for any other reason: It's less
/// efficient, has fewer features, and is more complicated.
+ ///
/// The message must be defined exactly as follows:
/// message Foo {
/// option message_set_wire_format = true;
@@ -3146,8 +3155,10 @@ namespace Google.Protobuf.Reflection {
/// }
/// Note that the message cannot have any defined fields; MessageSets only
/// have extensions.
+ ///
/// All extensions of your type must be singular messages; e.g. they cannot
/// be int32s, enums, or repeated messages.
+ ///
/// Because this is an option, the above two restrictions are not enforced by
/// the protocol compiler.
/// </summary>
@@ -3195,6 +3206,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Whether the message is an automatically generated map entry type for the
/// maps field.
+ ///
/// For maps fields:
/// map&lt;KeyType, ValueType> map_field = 1;
/// The parsed descriptor looks like:
@@ -3204,10 +3216,12 @@ namespace Google.Protobuf.Reflection {
/// optional ValueType value = 2;
/// }
/// repeated MapFieldEntry map_field = 1;
+ ///
/// Implementations may choose not to generate the map_entry=true message, but
/// use a native map in the target language to hold the keys and values.
/// The reflection APIs in such implementions still need to work as
/// if the field is a repeated message field.
+ ///
/// NOTE: Do not set the option in .proto files. Always use the maps syntax
/// instead. The option should only be implicitly set by the proto compiler
/// parser.
@@ -3261,7 +3275,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3360,7 +3374,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<FieldOptions> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[11]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[11]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3389,7 +3403,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "ctype" field.</summary>
public const int CtypeFieldNumber = 1;
- private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_ = global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING;
+ private global::Google.Protobuf.Reflection.FieldOptions.Types.CType ctype_ = 0;
/// <summary>
/// The ctype option instructs the C++ code generator to use a different
/// representation of the field than it normally would. See the specific
@@ -3422,7 +3436,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>Field number for the "jstype" field.</summary>
public const int JstypeFieldNumber = 6;
- private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_ = global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL;
+ private global::Google.Protobuf.Reflection.FieldOptions.Types.JSType jstype_ = 0;
/// <summary>
/// The jstype option determines the JavaScript type used for values of the
/// field. The option is permitted only for 64 bit integral and fixed types
@@ -3449,16 +3463,19 @@ namespace Google.Protobuf.Reflection {
/// fields. It means that when the outer message is initially parsed, the
/// inner message's contents will not be parsed but instead stored in encoded
/// form. The inner message will actually be parsed when it is first accessed.
+ ///
/// This is only a hint. Implementations are free to choose whether to use
/// eager or lazy parsing regardless of the value of this option. However,
/// setting this option true suggests that the protocol author believes that
/// using lazy parsing on this field is worth the additional bookkeeping
/// overhead typically needed to implement it.
+ ///
/// This option does not affect the public interface of any generated code;
/// all method signatures remain the same. Furthermore, thread-safety of the
/// interface is not affected by this option; const methods remain safe to
/// call from multiple threads concurrently, while non-const methods continue
/// to require exclusive access.
+ ///
/// Note that implementations may choose not to check required fields within
/// a lazy sub-message. That is, calling IsInitialized() on the outher message
/// may return true even if the inner message has missing required fields.
@@ -3541,9 +3558,9 @@ namespace Google.Protobuf.Reflection {
public override int GetHashCode() {
int hash = 1;
- if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) hash ^= Ctype.GetHashCode();
+ if (Ctype != 0) hash ^= Ctype.GetHashCode();
if (Packed != false) hash ^= Packed.GetHashCode();
- if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) hash ^= Jstype.GetHashCode();
+ if (Jstype != 0) hash ^= Jstype.GetHashCode();
if (Lazy != false) hash ^= Lazy.GetHashCode();
if (Deprecated != false) hash ^= Deprecated.GetHashCode();
if (Weak != false) hash ^= Weak.GetHashCode();
@@ -3552,11 +3569,11 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
- if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
+ if (Ctype != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) Ctype);
}
@@ -3572,7 +3589,7 @@ namespace Google.Protobuf.Reflection {
output.WriteRawTag(40);
output.WriteBool(Lazy);
}
- if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
+ if (Jstype != 0) {
output.WriteRawTag(48);
output.WriteEnum((int) Jstype);
}
@@ -3585,13 +3602,13 @@ namespace Google.Protobuf.Reflection {
public int CalculateSize() {
int size = 0;
- if (Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
+ if (Ctype != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Ctype);
}
if (Packed != false) {
size += 1 + 1;
}
- if (Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
+ if (Jstype != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Jstype);
}
if (Lazy != false) {
@@ -3611,13 +3628,13 @@ namespace Google.Protobuf.Reflection {
if (other == null) {
return;
}
- if (other.Ctype != global::Google.Protobuf.Reflection.FieldOptions.Types.CType.STRING) {
+ if (other.Ctype != 0) {
Ctype = other.Ctype;
}
if (other.Packed != false) {
Packed = other.Packed;
}
- if (other.Jstype != global::Google.Protobuf.Reflection.FieldOptions.Types.JSType.JS_NORMAL) {
+ if (other.Jstype != 0) {
Jstype = other.Jstype;
}
if (other.Lazy != false) {
@@ -3679,24 +3696,24 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Default mode.
/// </summary>
- STRING = 0,
- CORD = 1,
- STRING_PIECE = 2,
+ [pbr::OriginalName("STRING")] String = 0,
+ [pbr::OriginalName("CORD")] Cord = 1,
+ [pbr::OriginalName("STRING_PIECE")] StringPiece = 2,
}
internal enum JSType {
/// <summary>
/// Use the default type.
/// </summary>
- JS_NORMAL = 0,
+ [pbr::OriginalName("JS_NORMAL")] JsNormal = 0,
/// <summary>
/// Use JavaScript strings.
/// </summary>
- JS_STRING = 1,
+ [pbr::OriginalName("JS_STRING")] JsString = 1,
/// <summary>
/// Use JavaScript numbers.
/// </summary>
- JS_NUMBER = 2,
+ [pbr::OriginalName("JS_NUMBER")] JsNumber = 2,
}
}
@@ -3710,7 +3727,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<EnumOptions> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[12]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[12]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3801,7 +3818,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -3872,7 +3889,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<EnumValueOptions> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[13]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[13]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -3946,7 +3963,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4003,7 +4020,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<ServiceOptions> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[14]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[14]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4077,7 +4094,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4134,7 +4151,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<MethodOptions> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[15]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[15]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4208,7 +4225,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4273,7 +4290,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<UninterpretedOption> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[16]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[16]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4319,7 +4336,7 @@ namespace Google.Protobuf.Reflection {
public string IdentifierValue {
get { return identifierValue_; }
set {
- identifierValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ identifierValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -4359,7 +4376,7 @@ namespace Google.Protobuf.Reflection {
public pb::ByteString StringValue {
get { return stringValue_; }
set {
- stringValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ stringValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -4369,7 +4386,7 @@ namespace Google.Protobuf.Reflection {
public string AggregateValue {
get { return aggregateValue_; }
set {
- aggregateValue_ = pb::Preconditions.CheckNotNull(value, "value");
+ aggregateValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -4407,7 +4424,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4571,7 +4588,7 @@ namespace Google.Protobuf.Reflection {
public string NamePart_ {
get { return namePart_; }
set {
- namePart_ = pb::Preconditions.CheckNotNull(value, "value");
+ namePart_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -4609,7 +4626,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4682,7 +4699,7 @@ namespace Google.Protobuf.Reflection {
public static pb::MessageParser<SourceCodeInfo> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.Reflection.DescriptorProtoFile.Descriptor.MessageTypes[17]; }
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[17]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -4713,6 +4730,7 @@ namespace Google.Protobuf.Reflection {
/// corresponds to a particular definition. This information is intended
/// to be useful to IDEs, code indexers, documentation generators, and similar
/// tools.
+ ///
/// For example, say we have a file like:
/// message Foo {
/// optional string foo = 1;
@@ -4728,6 +4746,7 @@ namespace Google.Protobuf.Reflection {
/// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
/// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
/// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
+ ///
/// Notes:
/// - A location may refer to a repeated field itself (i.e. not to any
/// particular index within it). This is used whenever a set of elements are
@@ -4777,7 +4796,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -4855,6 +4874,7 @@ namespace Google.Protobuf.Reflection {
/// <summary>
/// Identifies which part of the FileDescriptorProto was defined at this
/// location.
+ ///
/// Each element is a field number or an index. They form a path from
/// the root FileDescriptorProto to the place where the definition. For
/// example, this path:
@@ -4869,6 +4889,7 @@ namespace Google.Protobuf.Reflection {
/// repeated FieldDescriptorProto field = 2;
/// and FieldDescriptorProto.name has field number 1:
/// optional string name = 1;
+ ///
/// Thus, the above path gives the location of a field name. If we removed
/// the last element:
/// [ 4, 3, 2, 7 ]
@@ -4902,31 +4923,41 @@ namespace Google.Protobuf.Reflection {
/// If this SourceCodeInfo represents a complete declaration, these are any
/// comments appearing before and after the declaration which appear to be
/// attached to the declaration.
+ ///
/// A series of line comments appearing on consecutive lines, with no other
/// tokens appearing on those lines, will be treated as a single comment.
+ ///
/// leading_detached_comments will keep paragraphs of comments that appear
/// before (but not connected to) the current element. Each paragraph,
/// separated by empty lines, will be one comment element in the repeated
/// field.
+ ///
/// Only the comment content is provided; comment markers (e.g. //) are
/// stripped out. For block comments, leading whitespace and an asterisk
/// will be stripped from the beginning of each line other than the first.
/// Newlines are included in the output.
+ ///
/// Examples:
+ ///
/// optional int32 foo = 1; // Comment attached to foo.
/// // Comment attached to bar.
/// optional int32 bar = 2;
+ ///
/// optional string baz = 3;
/// // Comment attached to baz.
/// // Another line attached to baz.
+ ///
/// // Comment attached to qux.
/// //
/// // Another line attached to qux.
/// optional double qux = 4;
+ ///
/// // Detached comment for corge. This is not leading or trailing comments
/// // to qux or corge because there are blank lines separating it from
/// // both.
+ ///
/// // Detached comment for corge paragraph 2.
+ ///
/// optional string corge = 5;
/// /* Block comment attached
/// * to corge. Leading asterisks
@@ -4934,12 +4965,13 @@ namespace Google.Protobuf.Reflection {
/// /* Block comment attached to
/// * grault. */
/// optional int32 grault = 6;
+ ///
/// // ignored detached comments.
/// </summary>
public string LeadingComments {
get { return leadingComments_; }
set {
- leadingComments_ = pb::Preconditions.CheckNotNull(value, "value");
+ leadingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -4949,7 +4981,7 @@ namespace Google.Protobuf.Reflection {
public string TrailingComments {
get { return trailingComments_; }
set {
- trailingComments_ = pb::Preconditions.CheckNotNull(value, "value");
+ trailingComments_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -4992,7 +5024,7 @@ namespace Google.Protobuf.Reflection {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -5078,6 +5110,310 @@ namespace Google.Protobuf.Reflection {
}
+ /// <summary>
+ /// Describes the relationship between generated code and its original source
+ /// file. A GeneratedCodeInfo message is associated with only one generated
+ /// source file, but may contain references to different source .proto files.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal sealed partial class GeneratedCodeInfo : pb::IMessage<GeneratedCodeInfo> {
+ private static readonly pb::MessageParser<GeneratedCodeInfo> _parser = new pb::MessageParser<GeneratedCodeInfo>(() => new GeneratedCodeInfo());
+ public static pb::MessageParser<GeneratedCodeInfo> Parser { get { return _parser; } }
+
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[18]; }
+ }
+
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ public GeneratedCodeInfo() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ public GeneratedCodeInfo(GeneratedCodeInfo other) : this() {
+ annotation_ = other.annotation_.Clone();
+ }
+
+ public GeneratedCodeInfo Clone() {
+ return new GeneratedCodeInfo(this);
+ }
+
+ /// <summary>Field number for the "annotation" field.</summary>
+ public const int AnnotationFieldNumber = 1;
+ private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> _repeated_annotation_codec
+ = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Parser);
+ private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> annotation_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation>();
+ /// <summary>
+ /// An Annotation connects some span of text in generated code to an element
+ /// of its generating .proto file.
+ /// </summary>
+ public pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> Annotation {
+ get { return annotation_; }
+ }
+
+ public override bool Equals(object other) {
+ return Equals(other as GeneratedCodeInfo);
+ }
+
+ public bool Equals(GeneratedCodeInfo other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!annotation_.Equals(other.annotation_)) return false;
+ return true;
+ }
+
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= annotation_.GetHashCode();
+ return hash;
+ }
+
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ public void WriteTo(pb::CodedOutputStream output) {
+ annotation_.WriteTo(output, _repeated_annotation_codec);
+ }
+
+ public int CalculateSize() {
+ int size = 0;
+ size += annotation_.CalculateSize(_repeated_annotation_codec);
+ return size;
+ }
+
+ public void MergeFrom(GeneratedCodeInfo other) {
+ if (other == null) {
+ return;
+ }
+ annotation_.Add(other.annotation_);
+ }
+
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ annotation_.AddEntriesFrom(input, _repeated_annotation_codec);
+ break;
+ }
+ }
+ }
+ }
+
+ #region Nested types
+ /// <summary>Container for nested types declared in the GeneratedCodeInfo message type.</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class Types {
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ internal sealed partial class Annotation : pb::IMessage<Annotation> {
+ private static readonly pb::MessageParser<Annotation> _parser = new pb::MessageParser<Annotation>(() => new Annotation());
+ public static pb::MessageParser<Annotation> Parser { get { return _parser; } }
+
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Google.Protobuf.Reflection.GeneratedCodeInfo.Descriptor.NestedTypes[0]; }
+ }
+
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ public Annotation() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ public Annotation(Annotation other) : this() {
+ path_ = other.path_.Clone();
+ sourceFile_ = other.sourceFile_;
+ begin_ = other.begin_;
+ end_ = other.end_;
+ }
+
+ public Annotation Clone() {
+ return new Annotation(this);
+ }
+
+ /// <summary>Field number for the "path" field.</summary>
+ public const int PathFieldNumber = 1;
+ private static readonly pb::FieldCodec<int> _repeated_path_codec
+ = pb::FieldCodec.ForInt32(10);
+ private readonly pbc::RepeatedField<int> path_ = new pbc::RepeatedField<int>();
+ /// <summary>
+ /// Identifies the element in the original source .proto file. This field
+ /// is formatted the same as SourceCodeInfo.Location.path.
+ /// </summary>
+ public pbc::RepeatedField<int> Path {
+ get { return path_; }
+ }
+
+ /// <summary>Field number for the "source_file" field.</summary>
+ public const int SourceFileFieldNumber = 2;
+ private string sourceFile_ = "";
+ /// <summary>
+ /// Identifies the filesystem path to the original source .proto.
+ /// </summary>
+ public string SourceFile {
+ get { return sourceFile_; }
+ set {
+ sourceFile_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "begin" field.</summary>
+ public const int BeginFieldNumber = 3;
+ private int begin_;
+ /// <summary>
+ /// Identifies the starting offset in bytes in the generated code
+ /// that relates to the identified object.
+ /// </summary>
+ public int Begin {
+ get { return begin_; }
+ set {
+ begin_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "end" field.</summary>
+ public const int EndFieldNumber = 4;
+ private int end_;
+ /// <summary>
+ /// Identifies the ending offset in bytes in the generated code that
+ /// relates to the identified offset. The end offset should be one past
+ /// the last relevant byte (so the length of the text = end - begin).
+ /// </summary>
+ public int End {
+ get { return end_; }
+ set {
+ end_ = value;
+ }
+ }
+
+ public override bool Equals(object other) {
+ return Equals(other as Annotation);
+ }
+
+ public bool Equals(Annotation other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!path_.Equals(other.path_)) return false;
+ if (SourceFile != other.SourceFile) return false;
+ if (Begin != other.Begin) return false;
+ if (End != other.End) return false;
+ return true;
+ }
+
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= path_.GetHashCode();
+ if (SourceFile.Length != 0) hash ^= SourceFile.GetHashCode();
+ if (Begin != 0) hash ^= Begin.GetHashCode();
+ if (End != 0) hash ^= End.GetHashCode();
+ return hash;
+ }
+
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ public void WriteTo(pb::CodedOutputStream output) {
+ path_.WriteTo(output, _repeated_path_codec);
+ if (SourceFile.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(SourceFile);
+ }
+ if (Begin != 0) {
+ output.WriteRawTag(24);
+ output.WriteInt32(Begin);
+ }
+ if (End != 0) {
+ output.WriteRawTag(32);
+ output.WriteInt32(End);
+ }
+ }
+
+ public int CalculateSize() {
+ int size = 0;
+ size += path_.CalculateSize(_repeated_path_codec);
+ if (SourceFile.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(SourceFile);
+ }
+ if (Begin != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(Begin);
+ }
+ if (End != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(End);
+ }
+ return size;
+ }
+
+ public void MergeFrom(Annotation other) {
+ if (other == null) {
+ return;
+ }
+ path_.Add(other.path_);
+ if (other.SourceFile.Length != 0) {
+ SourceFile = other.SourceFile;
+ }
+ if (other.Begin != 0) {
+ Begin = other.Begin;
+ }
+ if (other.End != 0) {
+ End = other.End;
+ }
+ }
+
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10:
+ case 8: {
+ path_.AddEntriesFrom(input, _repeated_path_codec);
+ break;
+ }
+ case 18: {
+ SourceFile = input.ReadString();
+ break;
+ }
+ case 24: {
+ Begin = input.ReadInt32();
+ break;
+ }
+ case 32: {
+ End = input.ReadInt32();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+ #endregion
+
+ }
+
#endregion
}
diff --git a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs
index 285f26f3..c732c93a 100644
--- a/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/EnumDescriptor.cs
@@ -43,13 +43,13 @@ namespace Google.Protobuf.Reflection
private readonly EnumDescriptorProto proto;
private readonly MessageDescriptor containingType;
private readonly IList<EnumValueDescriptor> values;
- private readonly Type generatedType;
+ private readonly Type clrType;
- internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, Type generatedType)
+ internal EnumDescriptor(EnumDescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int index, Type clrType)
: base(file, file.ComputeFullName(parent, proto.Name), index)
{
this.proto = proto;
- this.generatedType = generatedType;
+ this.clrType = clrType;
containingType = parent;
if (proto.Value.Count == 0)
@@ -73,9 +73,9 @@ namespace Google.Protobuf.Reflection
public override string Name { get { return proto.Name; } }
/// <summary>
- /// The generated type for this enum, or <c>null</c> if the descriptor does not represent a generated type.
+ /// The CLR type for this enum. For generated code, this will be a CLR enum type.
/// </summary>
- public Type GeneratedType { get { return generatedType; } }
+ public Type ClrType { get { return clrType; } }
/// <value>
/// If this is a nested type, get the outer descriptor, otherwise null.
diff --git a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
index 619a6ac8..6c6f6ee0 100644
--- a/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FieldDescriptor.cs
@@ -30,9 +30,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
-using System;
-using System.Linq;
using Google.Protobuf.Compatibility;
+using System;
namespace Google.Protobuf.Reflection
{
@@ -41,20 +40,35 @@ namespace Google.Protobuf.Reflection
/// </summary>
public sealed class FieldDescriptor : DescriptorBase, IComparable<FieldDescriptor>
{
- private readonly FieldDescriptorProto proto;
private EnumDescriptor enumType;
private MessageDescriptor messageType;
- private readonly MessageDescriptor containingType;
- private readonly OneofDescriptor containingOneof;
private FieldType fieldType;
private readonly string propertyName; // Annoyingly, needed in Crosslink.
private IFieldAccessor accessor;
+ /// <summary>
+ /// Get the field's containing message type.
+ /// </summary>
+ public MessageDescriptor ContainingType { get; }
+
+ /// <summary>
+ /// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
+ /// </summary>
+ public OneofDescriptor ContainingOneof { get; }
+
+ /// <summary>
+ /// The effective JSON name for this field. This is usually the lower-camel-cased form of the field name,
+ /// but can be overridden using the <c>json_name</c> option in the .proto file.
+ /// </summary>
+ public string JsonName { get; }
+
+ internal FieldDescriptorProto Proto { get; }
+
internal FieldDescriptor(FieldDescriptorProto proto, FileDescriptor file,
MessageDescriptor parent, int index, string propertyName)
: base(file, file.ComputeFullName(parent, proto.Name), index)
{
- this.proto = proto;
+ Proto = proto;
if (proto.Type != 0)
{
fieldType = GetFieldTypeFromProtoType(proto.Type);
@@ -62,19 +76,18 @@ namespace Google.Protobuf.Reflection
if (FieldNumber <= 0)
{
- throw new DescriptorValidationException(this,
- "Field numbers must be positive integers.");
+ throw new DescriptorValidationException(this, "Field numbers must be positive integers.");
}
- containingType = parent;
+ ContainingType = parent;
// OneofIndex "defaults" to -1 due to a hack in FieldDescriptor.OnConstruction.
if (proto.OneofIndex != -1)
{
if (proto.OneofIndex < 0 || proto.OneofIndex >= parent.Proto.OneofDecl.Count)
{
throw new DescriptorValidationException(this,
- "FieldDescriptorProto.oneof_index is out of range for type " + parent.Name);
+ $"FieldDescriptorProto.oneof_index is out of range for type {parent.Name}");
}
- containingOneof = parent.Oneofs[proto.OneofIndex];
+ ContainingOneof = parent.Oneofs[proto.OneofIndex];
}
file.DescriptorPool.AddSymbol(this);
@@ -84,25 +97,34 @@ namespace Google.Protobuf.Reflection
// We could trust the generated code and check whether the type of the property is
// a MapField, but that feels a tad nasty.
this.propertyName = propertyName;
+ JsonName = Proto.JsonName == "" ? JsonFormatter.ToCamelCase(Proto.Name) : Proto.JsonName;
}
+
/// <summary>
/// The brief name of the descriptor's target.
/// </summary>
- public override string Name { get { return proto.Name; } }
-
- internal FieldDescriptorProto Proto { get { return proto; } }
+ public override string Name => Proto.Name;
/// <summary>
- /// Returns the accessor for this field, or <c>null</c> if this descriptor does
- /// not support reflective access.
+ /// Returns the accessor for this field.
/// </summary>
/// <remarks>
+ /// <para>
/// While a <see cref="FieldDescriptor"/> describes the field, it does not provide
/// any way of obtaining or changing the value of the field within a specific message;
/// that is the responsibility of the accessor.
+ /// </para>
+ /// <para>
+ /// The value returned by this property will be non-null for all regular fields. However,
+ /// if a message containing a map field is introspected, the list of nested messages will include
+ /// an auto-generated nested key/value pair message for the field. This is not represented in any
+ /// generated type, and the value of the map field itself is represented by a dictionary in the
+ /// reflection API. There are never instances of those "hidden" messages, so no accessor is provided
+ /// and this property will return null.
+ /// </para>
/// </remarks>
- public IFieldAccessor Accessor { get { return accessor; } }
+ public IFieldAccessor Accessor => accessor;
/// <summary>
/// Maps a field type as included in the .proto file to a FieldType.
@@ -111,41 +133,41 @@ namespace Google.Protobuf.Reflection
{
switch (type)
{
- case FieldDescriptorProto.Types.Type.TYPE_DOUBLE:
+ case FieldDescriptorProto.Types.Type.Double:
return FieldType.Double;
- case FieldDescriptorProto.Types.Type.TYPE_FLOAT:
+ case FieldDescriptorProto.Types.Type.Float:
return FieldType.Float;
- case FieldDescriptorProto.Types.Type.TYPE_INT64:
+ case FieldDescriptorProto.Types.Type.Int64:
return FieldType.Int64;
- case FieldDescriptorProto.Types.Type.TYPE_UINT64:
+ case FieldDescriptorProto.Types.Type.Uint64:
return FieldType.UInt64;
- case FieldDescriptorProto.Types.Type.TYPE_INT32:
+ case FieldDescriptorProto.Types.Type.Int32:
return FieldType.Int32;
- case FieldDescriptorProto.Types.Type.TYPE_FIXED64:
+ case FieldDescriptorProto.Types.Type.Fixed64:
return FieldType.Fixed64;
- case FieldDescriptorProto.Types.Type.TYPE_FIXED32:
+ case FieldDescriptorProto.Types.Type.Fixed32:
return FieldType.Fixed32;
- case FieldDescriptorProto.Types.Type.TYPE_BOOL:
+ case FieldDescriptorProto.Types.Type.Bool:
return FieldType.Bool;
- case FieldDescriptorProto.Types.Type.TYPE_STRING:
+ case FieldDescriptorProto.Types.Type.String:
return FieldType.String;
- case FieldDescriptorProto.Types.Type.TYPE_GROUP:
+ case FieldDescriptorProto.Types.Type.Group:
return FieldType.Group;
- case FieldDescriptorProto.Types.Type.TYPE_MESSAGE:
+ case FieldDescriptorProto.Types.Type.Message:
return FieldType.Message;
- case FieldDescriptorProto.Types.Type.TYPE_BYTES:
+ case FieldDescriptorProto.Types.Type.Bytes:
return FieldType.Bytes;
- case FieldDescriptorProto.Types.Type.TYPE_UINT32:
+ case FieldDescriptorProto.Types.Type.Uint32:
return FieldType.UInt32;
- case FieldDescriptorProto.Types.Type.TYPE_ENUM:
+ case FieldDescriptorProto.Types.Type.Enum:
return FieldType.Enum;
- case FieldDescriptorProto.Types.Type.TYPE_SFIXED32:
+ case FieldDescriptorProto.Types.Type.Sfixed32:
return FieldType.SFixed32;
- case FieldDescriptorProto.Types.Type.TYPE_SFIXED64:
+ case FieldDescriptorProto.Types.Type.Sfixed64:
return FieldType.SFixed64;
- case FieldDescriptorProto.Types.Type.TYPE_SINT32:
+ case FieldDescriptorProto.Types.Type.Sint32:
return FieldType.SInt32;
- case FieldDescriptorProto.Types.Type.TYPE_SINT64:
+ case FieldDescriptorProto.Types.Type.Sint64:
return FieldType.SInt64;
default:
throw new ArgumentException("Invalid type specified");
@@ -155,62 +177,32 @@ namespace Google.Protobuf.Reflection
/// <summary>
/// Returns <c>true</c> if this field is a repeated field; <c>false</c> otherwise.
/// </summary>
- public bool IsRepeated
- {
- get { return Proto.Label == FieldDescriptorProto.Types.Label.LABEL_REPEATED; }
- }
+ public bool IsRepeated => Proto.Label == FieldDescriptorProto.Types.Label.Repeated;
/// <summary>
/// Returns <c>true</c> if this field is a map field; <c>false</c> otherwise.
/// </summary>
- public bool IsMap
- {
- get { return fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry; }
- }
+ public bool IsMap => fieldType == FieldType.Message && messageType.Proto.Options != null && messageType.Proto.Options.MapEntry;
/// <summary>
/// Returns <c>true</c> if this field is a packed, repeated field; <c>false</c> otherwise.
/// </summary>
- public bool IsPacked
- {
+ public bool IsPacked =>
// Note the || rather than && here - we're effectively defaulting to packed, because that *is*
// the default in proto3, which is all we support. We may give the wrong result for the protos
// within descriptor.proto, but that's okay, as they're never exposed and we don't use IsPacked
// within the runtime.
- get { return Proto.Options == null || Proto.Options.Packed; }
- }
-
- /// <summary>
- /// Get the field's containing message type.
- /// </summary>
- public MessageDescriptor ContainingType
- {
- get { return containingType; }
- }
-
- /// <summary>
- /// Returns the oneof containing this field, or <c>null</c> if it is not part of a oneof.
- /// </summary>
- public OneofDescriptor ContainingOneof
- {
- get { return containingOneof; }
- }
-
+ Proto.Options == null || Proto.Options.Packed;
+
/// <summary>
- /// Returns the type of the field.
+ /// Returns the type of the field.
/// </summary>
- public FieldType FieldType
- {
- get { return fieldType; }
- }
+ public FieldType FieldType => fieldType;
/// <summary>
/// Returns the field number declared in the proto file.
/// </summary>
- public int FieldNumber
- {
- get { return Proto.Number; }
- }
+ public int FieldNumber => Proto.Number;
/// <summary>
/// Compares this descriptor with another one, ordering in "canonical" order
@@ -220,7 +212,7 @@ namespace Google.Protobuf.Reflection
/// </summary>
public int CompareTo(FieldDescriptor other)
{
- if (other.containingType != containingType)
+ if (other.ContainingType != ContainingType)
{
throw new ArgumentException("FieldDescriptors can only be compared to other FieldDescriptors " +
"for fields of the same message type.");
@@ -281,7 +273,7 @@ namespace Google.Protobuf.Reflection
}
else
{
- throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not a type.");
+ throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not a type.");
}
}
@@ -289,8 +281,7 @@ namespace Google.Protobuf.Reflection
{
if (!(typeDescriptor is MessageDescriptor))
{
- throw new DescriptorValidationException(this,
- "\"" + Proto.TypeName + "\" is not a message type.");
+ throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not a message type.");
}
messageType = (MessageDescriptor) typeDescriptor;
@@ -303,7 +294,7 @@ namespace Google.Protobuf.Reflection
{
if (!(typeDescriptor is EnumDescriptor))
{
- throw new DescriptorValidationException(this, "\"" + Proto.TypeName + "\" is not an enum type.");
+ throw new DescriptorValidationException(this, $"\"{Proto.TypeName}\" is not an enum type.");
}
enumType = (EnumDescriptor) typeDescriptor;
}
@@ -324,23 +315,25 @@ namespace Google.Protobuf.Reflection
File.DescriptorPool.AddFieldByNumber(this);
- if (containingType != null && containingType.Proto.Options != null && containingType.Proto.Options.MessageSetWireFormat)
+ if (ContainingType != null && ContainingType.Proto.Options != null && ContainingType.Proto.Options.MessageSetWireFormat)
{
throw new DescriptorValidationException(this, "MessageSet format is not supported.");
}
- accessor = CreateAccessor(propertyName);
+ accessor = CreateAccessor();
}
- private IFieldAccessor CreateAccessor(string propertyName)
+ private IFieldAccessor CreateAccessor()
{
- if (containingType.GeneratedType == null || propertyName == null)
+ // If we're given no property name, that's because we really don't want an accessor.
+ // (At the moment, that means it's a map entry message...)
+ if (propertyName == null)
{
return null;
}
- var property = containingType.GeneratedType.GetProperty(propertyName);
+ var property = ContainingType.ClrType.GetProperty(propertyName);
if (property == null)
{
- throw new DescriptorValidationException(this, "Property " + propertyName + " not found in " + containingType.GeneratedType);
+ throw new DescriptorValidationException(this, $"Property {propertyName} not found in {ContainingType.ClrType}");
}
return IsMap ? new MapFieldAccessor(property, this)
: IsRepeated ? new RepeatedFieldAccessor(property, this)
diff --git a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
index 45862aff..ab7cd922 100644
--- a/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/FileDescriptor.cs
@@ -43,35 +43,26 @@ namespace Google.Protobuf.Reflection
/// </summary>
public sealed class FileDescriptor : IDescriptor
{
- private readonly ByteString descriptorData;
- private readonly FileDescriptorProto proto;
- private readonly IList<MessageDescriptor> messageTypes;
- private readonly IList<EnumDescriptor> enumTypes;
- private readonly IList<ServiceDescriptor> services;
- private readonly IList<FileDescriptor> dependencies;
- private readonly IList<FileDescriptor> publicDependencies;
- private readonly DescriptorPool pool;
-
- private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo)
+ private FileDescriptor(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, DescriptorPool pool, bool allowUnknownDependencies, GeneratedClrTypeInfo generatedCodeInfo)
{
- this.descriptorData = descriptorData;
- this.pool = pool;
- this.proto = proto;
- this.dependencies = new ReadOnlyCollection<FileDescriptor>((FileDescriptor[]) dependencies.Clone());
+ SerializedData = descriptorData;
+ DescriptorPool = pool;
+ Proto = proto;
+ Dependencies = new ReadOnlyCollection<FileDescriptor>((FileDescriptor[]) dependencies.Clone());
- publicDependencies = DeterminePublicDependencies(this, proto, dependencies, allowUnknownDependencies);
+ PublicDependencies = DeterminePublicDependencies(this, proto, dependencies, allowUnknownDependencies);
pool.AddPackage(Package, this);
- messageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageType,
+ MessageTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.MessageType,
(message, index) =>
- new MessageDescriptor(message, this, null, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedTypes[index]));
+ new MessageDescriptor(message, this, null, index, generatedCodeInfo.NestedTypes[index]));
- enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumType,
+ EnumTypes = DescriptorUtil.ConvertAndMakeReadOnly(proto.EnumType,
(enumType, index) =>
- new EnumDescriptor(enumType, this, null, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedEnums[index]));
+ new EnumDescriptor(enumType, this, null, index, generatedCodeInfo.NestedEnums[index]));
- services = DescriptorUtil.ConvertAndMakeReadOnly(proto.Service,
+ Services = DescriptorUtil.ConvertAndMakeReadOnly(proto.Service,
(service, index) =>
new ServiceDescriptor(service, this, index));
}
@@ -132,99 +123,63 @@ namespace Google.Protobuf.Reflection
/// <value>
/// The descriptor in its protocol message representation.
/// </value>
- internal FileDescriptorProto Proto
- {
- get { return proto; }
- }
+ internal FileDescriptorProto Proto { get; }
/// <value>
/// The file name.
/// </value>
- public string Name
- {
- get { return proto.Name; }
- }
+ public string Name => Proto.Name;
/// <summary>
/// The package as declared in the .proto file. This may or may not
/// be equivalent to the .NET namespace of the generated classes.
/// </summary>
- public string Package
- {
- get { return proto.Package; }
- }
+ public string Package => Proto.Package;
/// <value>
/// Unmodifiable list of top-level message types declared in this file.
/// </value>
- public IList<MessageDescriptor> MessageTypes
- {
- get { return messageTypes; }
- }
+ public IList<MessageDescriptor> MessageTypes { get; }
/// <value>
/// Unmodifiable list of top-level enum types declared in this file.
/// </value>
- public IList<EnumDescriptor> EnumTypes
- {
- get { return enumTypes; }
- }
+ public IList<EnumDescriptor> EnumTypes { get; }
/// <value>
/// Unmodifiable list of top-level services declared in this file.
/// </value>
- public IList<ServiceDescriptor> Services
- {
- get { return services; }
- }
+ public IList<ServiceDescriptor> Services { get; }
/// <value>
/// Unmodifiable list of this file's dependencies (imports).
/// </value>
- public IList<FileDescriptor> Dependencies
- {
- get { return dependencies; }
- }
+ public IList<FileDescriptor> Dependencies { get; }
/// <value>
/// Unmodifiable list of this file's public dependencies (public imports).
/// </value>
- public IList<FileDescriptor> PublicDependencies
- {
- get { return publicDependencies; }
- }
+ public IList<FileDescriptor> PublicDependencies { get; }
/// <value>
/// The original serialized binary form of this descriptor.
/// </value>
- public ByteString SerializedData
- {
- get { return descriptorData; }
- }
+ public ByteString SerializedData { get; }
/// <value>
/// Implementation of IDescriptor.FullName - just returns the same as Name.
/// </value>
- string IDescriptor.FullName
- {
- get { return Name; }
- }
+ string IDescriptor.FullName => Name;
/// <value>
/// Implementation of IDescriptor.File - just returns this descriptor.
/// </value>
- FileDescriptor IDescriptor.File
- {
- get { return this; }
- }
+ FileDescriptor IDescriptor.File => this;
/// <value>
/// Pool containing symbol descriptors.
/// </value>
- internal DescriptorPool DescriptorPool
- {
- get { return pool; }
- }
+ internal DescriptorPool DescriptorPool { get; }
/// <summary>
/// Finds a type (message, enum, service or extension) in the file by name. Does not find nested types.
@@ -245,7 +200,7 @@ namespace Google.Protobuf.Reflection
{
name = Package + "." + name;
}
- T result = pool.FindSymbol<T>(name);
+ T result = DescriptorPool.FindSymbol<T>(name);
if (result != null && result.File == this)
{
return result;
@@ -264,11 +219,11 @@ namespace Google.Protobuf.Reflection
/// file's dependencies, in the exact order listed in the .proto file. May be null,
/// in which case it is treated as an empty array.</param>
/// <param name="allowUnknownDependencies">Whether unknown dependencies are ignored (true) or cause an exception to be thrown (false).</param>
- /// <param name="generatedCodeInfo">Reflection information, if any. May be null, specifically for non-generated code.</param>
+ /// <param name="generatedCodeInfo">Details about generated code, for the purposes of reflection.</param>
/// <exception cref="DescriptorValidationException">If <paramref name="proto"/> is not
/// a valid descriptor. This can occur for a number of reasons, such as a field
/// having an undefined type or because two messages were defined with the same name.</exception>
- private static FileDescriptor BuildFrom(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, bool allowUnknownDependencies, GeneratedCodeInfo generatedCodeInfo)
+ private static FileDescriptor BuildFrom(ByteString descriptorData, FileDescriptorProto proto, FileDescriptor[] dependencies, bool allowUnknownDependencies, GeneratedClrTypeInfo generatedCodeInfo)
{
// Building descriptors involves two steps: translating and linking.
// In the translation step (implemented by FileDescriptor's
@@ -291,15 +246,17 @@ namespace Google.Protobuf.Reflection
// need.
if (dependencies.Length != proto.Dependency.Count)
{
- throw new DescriptorValidationException(result,
- "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
- "those listed in the FileDescriptorProto.");
+ throw new DescriptorValidationException(
+ result,
+ "Dependencies passed to FileDescriptor.BuildFrom() don't match " +
+ "those listed in the FileDescriptorProto.");
}
for (int i = 0; i < proto.Dependency.Count; i++)
{
if (dependencies[i].Name != proto.Dependency[i])
{
- throw new DescriptorValidationException(result,
+ throw new DescriptorValidationException(
+ result,
"Dependencies passed to FileDescriptor.BuildFrom() don't match " +
"those listed in the FileDescriptorProto. Expected: " +
proto.Dependency[i] + " but was: " + dependencies[i].Name);
@@ -312,28 +269,29 @@ namespace Google.Protobuf.Reflection
private void CrossLink()
{
- foreach (MessageDescriptor message in messageTypes)
+ foreach (MessageDescriptor message in MessageTypes)
{
message.CrossLink();
}
- foreach (ServiceDescriptor service in services)
+ foreach (ServiceDescriptor service in Services)
{
service.CrossLink();
}
}
/// <summary>
- /// Creates an instance for generated code.
+ /// Creates a descriptor for generated code.
/// </summary>
/// <remarks>
- /// The <paramref name="generatedCodeInfo"/> parameter should be null for descriptors which don't correspond to
- /// generated types. Otherwise, it should be a <see cref="GeneratedCodeInfo"/> with nested types and nested
- /// enums corresponding to the types and enums contained within the file descriptor.
+ /// This method is only designed to be used by the results of generating code with protoc,
+ /// which creates the appropriate dependencies etc. It has to be public because the generated
+ /// code is "external", but should not be called directly by end users.
/// </remarks>
- public static FileDescriptor InternalBuildGeneratedFileFrom(byte[] descriptorData,
- FileDescriptor[] dependencies,
- GeneratedCodeInfo generatedCodeInfo)
+ public static FileDescriptor FromGeneratedCode(
+ byte[] descriptorData,
+ FileDescriptor[] dependencies,
+ GeneratedClrTypeInfo generatedCodeInfo)
{
FileDescriptorProto proto;
try
@@ -345,8 +303,6 @@ namespace Google.Protobuf.Reflection
throw new ArgumentException("Failed to parse protocol buffer descriptor for generated code.", e);
}
-
-
try
{
// When building descriptors for generated code, we allow unknown
@@ -355,7 +311,7 @@ namespace Google.Protobuf.Reflection
}
catch (DescriptorValidationException e)
{
- throw new ArgumentException("Invalid embedded descriptor for \"" + proto.Name + "\".", e);
+ throw new ArgumentException($"Invalid embedded descriptor for \"{proto.Name}\".", e);
}
}
@@ -367,7 +323,7 @@ namespace Google.Protobuf.Reflection
/// </returns>
public override string ToString()
{
- return "FileDescriptor for " + proto.Name;
+ return $"FileDescriptor for {Name}";
}
/// <summary>
@@ -383,6 +339,6 @@ namespace Google.Protobuf.Reflection
/// <value>
/// The file descriptor for <c>descriptor.proto</c>.
/// </value>
- public static FileDescriptor DescriptorProtoFileDescriptor { get { return DescriptorProtoFile.Descriptor; } }
+ public static FileDescriptor DescriptorProtoFileDescriptor { get { return DescriptorReflection.Descriptor; } }
}
} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs
new file mode 100644
index 00000000..fe5db656
--- /dev/null
+++ b/csharp/src/Google.Protobuf/Reflection/GeneratedClrTypeInfo.cs
@@ -0,0 +1,103 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 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.
+#endregion
+using System;
+
+namespace Google.Protobuf.Reflection
+{
+ /// <summary>
+ /// Extra information provided by generated code when initializing a message or file descriptor.
+ /// These are constructed as required, and are not long-lived. Hand-written code should
+ /// never need to use this type.
+ /// </summary>
+ public sealed class GeneratedClrTypeInfo
+ {
+ private static readonly string[] EmptyNames = new string[0];
+ private static readonly GeneratedClrTypeInfo[] EmptyCodeInfo = new GeneratedClrTypeInfo[0];
+
+ /// <summary>
+ /// Irrelevant for file descriptors; the CLR type for the message for message descriptors.
+ /// </summary>
+ public Type ClrType { get; private set; }
+
+ /// <summary>
+ /// Irrelevant for file descriptors; the parser for message descriptors.
+ /// </summary>
+ public MessageParser Parser { get; }
+
+ /// <summary>
+ /// Irrelevant for file descriptors; the CLR property names (in message descriptor field order)
+ /// for fields in the message for message descriptors.
+ /// </summary>
+ public string[] PropertyNames { get; }
+
+ /// <summary>
+ /// Irrelevant for file descriptors; the CLR property "base" names (in message descriptor oneof order)
+ /// for oneofs in the message for message descriptors. It is expected that for a oneof name of "Foo",
+ /// there will be a "FooCase" property and a "ClearFoo" method.
+ /// </summary>
+ public string[] OneofNames { get; }
+
+ /// <summary>
+ /// The reflection information for types within this file/message descriptor. Elements may be null
+ /// if there is no corresponding generated type, e.g. for map entry types.
+ /// </summary>
+ public GeneratedClrTypeInfo[] NestedTypes { get; }
+
+ /// <summary>
+ /// The CLR types for enums within this file/message descriptor.
+ /// </summary>
+ public Type[] NestedEnums { get; }
+
+ /// <summary>
+ /// Creates a GeneratedClrTypeInfo for a message descriptor, with nested types, nested enums, the CLR type, property names and oneof names.
+ /// Each array parameter may be null, to indicate a lack of values.
+ /// The parameter order is designed to make it feasible to format the generated code readably.
+ /// </summary>
+ public GeneratedClrTypeInfo(Type clrType, MessageParser parser, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes)
+ {
+ NestedTypes = nestedTypes ?? EmptyCodeInfo;
+ NestedEnums = nestedEnums ?? ReflectionUtil.EmptyTypes;
+ ClrType = clrType;
+ Parser = parser;
+ PropertyNames = propertyNames ?? EmptyNames;
+ OneofNames = oneofNames ?? EmptyNames;
+ }
+
+ /// <summary>
+ /// Creates a GeneratedClrTypeInfo for a file descriptor, with only types and enums.
+ /// </summary>
+ public GeneratedClrTypeInfo(Type[] nestedEnums, GeneratedClrTypeInfo[] nestedTypes)
+ : this(null, null, null, null, nestedEnums, nestedTypes)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs b/csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs
deleted file mode 100644
index 8c52cd12..00000000
--- a/csharp/src/Google.Protobuf/Reflection/GeneratedCodeInfo.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-
-namespace Google.Protobuf.Reflection
-{
- /// <summary>
- /// Extra information provided by generated code when initializing a message or file descriptor.
- /// These are constructed as required, and are not long-lived. Hand-written code should
- /// never need to use this type.
- /// </summary>
- public sealed class GeneratedCodeInfo
- {
- private static readonly string[] EmptyNames = new string[0];
- private static readonly GeneratedCodeInfo[] EmptyCodeInfo = new GeneratedCodeInfo[0];
-
- /// <summary>
- /// Irrelevant for file descriptors; the CLR type for the message for message descriptors.
- /// </summary>
- public Type ClrType { get; private set; }
-
- /// <summary>
- /// Irrelevant for file descriptors; the CLR property names (in message descriptor field order)
- /// for fields in the message for message descriptors.
- /// </summary>
- public string[] PropertyNames { get; private set; }
-
- /// <summary>
- /// Irrelevant for file descriptors; the CLR property "base" names (in message descriptor oneof order)
- /// for oneofs in the message for message descriptors. It is expected that for a oneof name of "Foo",
- /// there will be a "FooCase" property and a "ClearFoo" method.
- /// </summary>
- public string[] OneofNames { get; private set; }
-
- /// <summary>
- /// The reflection information for types within this file/message descriptor. Elements may be null
- /// if there is no corresponding generated type, e.g. for map entry types.
- /// </summary>
- public GeneratedCodeInfo[] NestedTypes { get; private set; }
-
- /// <summary>
- /// The CLR types for enums within this file/message descriptor.
- /// </summary>
- public Type[] NestedEnums { get; private set; }
-
- /// <summary>
- /// Creates a GeneratedCodeInfo for a message descriptor, with nested types, nested enums, the CLR type, property names and oneof names.
- /// Each array parameter may be null, to indicate a lack of values.
- /// The parameter order is designed to make it feasible to format the generated code readably.
- /// </summary>
- public GeneratedCodeInfo(Type clrType, string[] propertyNames, string[] oneofNames, Type[] nestedEnums, GeneratedCodeInfo[] nestedTypes)
- {
- NestedTypes = nestedTypes ?? EmptyCodeInfo;
- NestedEnums = nestedEnums ?? ReflectionUtil.EmptyTypes;
- ClrType = clrType;
- PropertyNames = propertyNames ?? EmptyNames;
- OneofNames = oneofNames ?? EmptyNames;
- }
-
- /// <summary>
- /// Creates a GeneratedCodeInfo for a file descriptor, with only types and enums.
- /// </summary>
- public GeneratedCodeInfo(Type[] nestedEnums, GeneratedCodeInfo[] nestedTypes)
- : this(null, null, null, nestedEnums, nestedTypes)
- {
- }
- }
-} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
index 82901f1b..f5a835e5 100644
--- a/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/MessageDescriptor.cs
@@ -56,139 +56,156 @@ namespace Google.Protobuf.Reflection
"google/protobuf/type.proto",
};
- private readonly DescriptorProto proto;
- private readonly MessageDescriptor containingType;
- private readonly IList<MessageDescriptor> nestedTypes;
- private readonly IList<EnumDescriptor> enumTypes;
private readonly IList<FieldDescriptor> fieldsInDeclarationOrder;
private readonly IList<FieldDescriptor> fieldsInNumberOrder;
- private readonly FieldCollection fields;
- private readonly IList<OneofDescriptor> oneofs;
- // CLR representation of the type described by this descriptor, if any.
- private readonly Type generatedType;
+ private readonly IDictionary<string, FieldDescriptor> jsonFieldMap;
- internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, GeneratedCodeInfo generatedCodeInfo)
+ internal MessageDescriptor(DescriptorProto proto, FileDescriptor file, MessageDescriptor parent, int typeIndex, GeneratedClrTypeInfo generatedCodeInfo)
: base(file, file.ComputeFullName(parent, proto.Name), typeIndex)
{
- this.proto = proto;
- generatedType = generatedCodeInfo == null ? null : generatedCodeInfo.ClrType;
+ Proto = proto;
+ Parser = generatedCodeInfo?.Parser;
+ ClrType = generatedCodeInfo?.ClrType;
+ ContainingType = parent;
- containingType = parent;
-
- oneofs = DescriptorUtil.ConvertAndMakeReadOnly(
+ // Note use of generatedCodeInfo. rather than generatedCodeInfo?. here... we don't expect
+ // to see any nested oneofs, types or enums in "not actually generated" code... we do
+ // expect fields though (for map entry messages).
+ Oneofs = DescriptorUtil.ConvertAndMakeReadOnly(
proto.OneofDecl,
(oneof, index) =>
- new OneofDescriptor(oneof, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.OneofNames[index]));
+ new OneofDescriptor(oneof, file, this, index, generatedCodeInfo.OneofNames[index]));
- nestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(
+ NestedTypes = DescriptorUtil.ConvertAndMakeReadOnly(
proto.NestedType,
(type, index) =>
- new MessageDescriptor(type, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedTypes[index]));
+ new MessageDescriptor(type, file, this, index, generatedCodeInfo.NestedTypes[index]));
- enumTypes = DescriptorUtil.ConvertAndMakeReadOnly(
+ EnumTypes = DescriptorUtil.ConvertAndMakeReadOnly(
proto.EnumType,
(type, index) =>
- new EnumDescriptor(type, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.NestedEnums[index]));
+ new EnumDescriptor(type, file, this, index, generatedCodeInfo.NestedEnums[index]));
fieldsInDeclarationOrder = DescriptorUtil.ConvertAndMakeReadOnly(
proto.Field,
(field, index) =>
- new FieldDescriptor(field, file, this, index, generatedCodeInfo == null ? null : generatedCodeInfo.PropertyNames[index]));
+ new FieldDescriptor(field, file, this, index, generatedCodeInfo?.PropertyNames[index]));
fieldsInNumberOrder = new ReadOnlyCollection<FieldDescriptor>(fieldsInDeclarationOrder.OrderBy(field => field.FieldNumber).ToArray());
+ // TODO: Use field => field.Proto.JsonName when we're confident it's appropriate. (And then use it in the formatter, too.)
+ jsonFieldMap = CreateJsonFieldMap(fieldsInNumberOrder);
file.DescriptorPool.AddSymbol(this);
- fields = new FieldCollection(this);
+ Fields = new FieldCollection(this);
}
-
- /// <summary>
- /// Returns the total number of nested types and enums, recursively.
- /// </summary>
- private int CountTotalGeneratedTypes()
+
+ private static ReadOnlyDictionary<string, FieldDescriptor> CreateJsonFieldMap(IList<FieldDescriptor> fields)
{
- return nestedTypes.Sum(nested => nested.CountTotalGeneratedTypes()) + enumTypes.Count;
+ var map = new Dictionary<string, FieldDescriptor>();
+ foreach (var field in fields)
+ {
+ map[field.Name] = field;
+ map[field.JsonName] = field;
+ }
+ return new ReadOnlyDictionary<string, FieldDescriptor>(map);
}
/// <summary>
/// The brief name of the descriptor's target.
/// </summary>
- public override string Name { get { return proto.Name; } }
+ public override string Name => Proto.Name;
- internal DescriptorProto Proto { get { return proto; } }
+ internal DescriptorProto Proto { get; }
/// <summary>
- /// The generated type for this message, or <c>null</c> if the descriptor does not represent a generated type.
+ /// The CLR type used to represent message instances from this descriptor.
/// </summary>
- public Type GeneratedType { get { return generatedType; } }
+ /// <remarks>
+ /// <para>
+ /// The value returned by this property will be non-null for all regular fields. However,
+ /// if a message containing a map field is introspected, the list of nested messages will include
+ /// an auto-generated nested key/value pair message for the field. This is not represented in any
+ /// generated type, so this property will return null in such cases.
+ /// </para>
+ /// <para>
+ /// For wrapper types (<see cref="Google.Protobuf.WellKnownTypes.StringValue"/> and the like), the type returned here
+ /// will be the generated message type, not the native type used by reflection for fields of those types. Code
+ /// using reflection should call <see cref="IsWrapperType"/> to determine whether a message descriptor represents
+ /// a wrapper type, and handle the result appropriately.
+ /// </para>
+ /// </remarks>
+ public Type ClrType { get; }
+
+ /// <summary>
+ /// A parser for this message type.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// As <see cref="MessageDescriptor"/> is not generic, this cannot be statically
+ /// typed to the relevant type, but it should produce objects of a type compatible with <see cref="ClrType"/>.
+ /// </para>
+ /// <para>
+ /// The value returned by this property will be non-null for all regular fields. However,
+ /// if a message containing a map field is introspected, the list of nested messages will include
+ /// an auto-generated nested key/value pair message for the field. No message parser object is created for
+ /// such messages, so this property will return null in such cases.
+ /// </para>
+ /// <para>
+ /// For wrapper types (<see cref="Google.Protobuf.WellKnownTypes.StringValue"/> and the like), the parser returned here
+ /// will be the generated message type, not the native type used by reflection for fields of those types. Code
+ /// using reflection should call <see cref="IsWrapperType"/> to determine whether a message descriptor represents
+ /// a wrapper type, and handle the result appropriately.
+ /// </para>
+ /// </remarks>
+ public MessageParser Parser { get; }
/// <summary>
/// Returns whether this message is one of the "well known types" which may have runtime/protoc support.
/// </summary>
- internal bool IsWellKnownType
- {
- get
- {
- return File.Package == "google.protobuf" && WellKnownTypeNames.Contains(File.Name);
- }
- }
+ internal bool IsWellKnownType => File.Package == "google.protobuf" && WellKnownTypeNames.Contains(File.Name);
+
+ /// <summary>
+ /// Returns whether this message is one of the "wrapper types" used for fields which represent primitive values
+ /// with the addition of presence.
+ /// </summary>
+ internal bool IsWrapperType => File.Package == "google.protobuf" && File.Name == "google/protobuf/wrappers.proto";
/// <value>
/// If this is a nested type, get the outer descriptor, otherwise null.
/// </value>
- public MessageDescriptor ContainingType
- {
- get { return containingType; }
- }
+ public MessageDescriptor ContainingType { get; }
/// <value>
/// A collection of fields, which can be retrieved by name or field number.
/// </value>
- public FieldCollection Fields
- {
- get { return fields; }
- }
+ public FieldCollection Fields { get; }
/// <value>
/// An unmodifiable list of this message type's nested types.
/// </value>
- public IList<MessageDescriptor> NestedTypes
- {
- get { return nestedTypes; }
- }
+ public IList<MessageDescriptor> NestedTypes { get; }
/// <value>
/// An unmodifiable list of this message type's enum types.
/// </value>
- public IList<EnumDescriptor> EnumTypes
- {
- get { return enumTypes; }
- }
+ public IList<EnumDescriptor> EnumTypes { get; }
/// <value>
/// An unmodifiable list of the "oneof" field collections in this message type.
/// </value>
- public IList<OneofDescriptor> Oneofs
- {
- get { return oneofs; }
- }
+ public IList<OneofDescriptor> Oneofs { get; }
/// <summary>
/// Finds a field by field name.
/// </summary>
/// <param name="name">The unqualified name of the field (e.g. "foo").</param>
/// <returns>The field's descriptor, or null if not found.</returns>
- public FieldDescriptor FindFieldByName(String name)
- {
- return File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name);
- }
+ public FieldDescriptor FindFieldByName(String name) => File.DescriptorPool.FindSymbol<FieldDescriptor>(FullName + "." + name);
/// <summary>
/// Finds a field by field number.
/// </summary>
/// <param name="number">The field number within this message type.</param>
/// <returns>The field's descriptor, or null if not found.</returns>
- public FieldDescriptor FindFieldByNumber(int number)
- {
- return File.DescriptorPool.FindFieldByNumber(this, number);
- }
+ public FieldDescriptor FindFieldByNumber(int number) => File.DescriptorPool.FindFieldByNumber(this, number);
/// <summary>
/// Finds a nested descriptor by name. The is valid for fields, nested
@@ -196,18 +213,15 @@ namespace Google.Protobuf.Reflection
/// </summary>
/// <param name="name">The unqualified name of the descriptor, e.g. "Foo"</param>
/// <returns>The descriptor, or null if not found.</returns>
- public T FindDescriptor<T>(string name)
- where T : class, IDescriptor
- {
- return File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
- }
+ public T FindDescriptor<T>(string name) where T : class, IDescriptor =>
+ File.DescriptorPool.FindSymbol<T>(FullName + "." + name);
/// <summary>
/// Looks up and cross-links all fields and nested types.
/// </summary>
internal void CrossLink()
{
- foreach (MessageDescriptor message in nestedTypes)
+ foreach (MessageDescriptor message in NestedTypes)
{
message.CrossLink();
}
@@ -217,7 +231,7 @@ namespace Google.Protobuf.Reflection
field.CrossLink();
}
- foreach (OneofDescriptor oneof in oneofs)
+ foreach (OneofDescriptor oneof in Oneofs)
{
oneof.CrossLink();
}
@@ -239,10 +253,7 @@ namespace Google.Protobuf.Reflection
/// Returns the fields in the message as an immutable list, in the order in which they
/// are declared in the source .proto file.
/// </value>
- public IList<FieldDescriptor> InDeclarationOrder()
- {
- return messageDescriptor.fieldsInDeclarationOrder;
- }
+ public IList<FieldDescriptor> InDeclarationOrder() => messageDescriptor.fieldsInDeclarationOrder;
/// <value>
/// Returns the fields in the message as an immutable list, in ascending field number
@@ -250,10 +261,17 @@ namespace Google.Protobuf.Reflection
/// index in the list to the field number; to retrieve a field by field number, it is better
/// to use the <see cref="FieldCollection"/> indexer.
/// </value>
- public IList<FieldDescriptor> InFieldNumberOrder()
- {
- return messageDescriptor.fieldsInNumberOrder;
- }
+ public IList<FieldDescriptor> InFieldNumberOrder() => messageDescriptor.fieldsInNumberOrder;
+
+ // TODO: consider making this public in the future. (Being conservative for now...)
+
+ /// <value>
+ /// Returns a read-only dictionary mapping the field names in this message as they're available
+ /// in the JSON representation to the field descriptors. For example, a field <c>foo_bar</c>
+ /// in the message would result two entries, one with a key <c>fooBar</c> and one with a key
+ /// <c>foo_bar</c>, both referring to the same field.
+ /// </value>
+ internal IDictionary<string, FieldDescriptor> ByJsonName() => messageDescriptor.jsonFieldMap;
/// <summary>
/// Retrieves the descriptor for the field with the given number.
diff --git a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
index d51ee526..22020acf 100644
--- a/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/OneofDescriptor.cs
@@ -86,8 +86,7 @@ namespace Google.Protobuf.Reflection
/// in a particular message.
/// </summary>
/// <value>
- /// The accessor used for reflective access, or <c>null</c> if reflection is not
- /// supported by this descriptor.
+ /// The accessor used for reflective access.
/// </value>
public OneofAccessor Accessor { get { return accessor; } }
@@ -106,19 +105,15 @@ namespace Google.Protobuf.Reflection
private OneofAccessor CreateAccessor(string clrName)
{
- if (containingType.GeneratedType == null || clrName == null)
- {
- return null;
- }
- var caseProperty = containingType.GeneratedType.GetProperty(clrName + "Case");
+ var caseProperty = containingType.ClrType.GetProperty(clrName + "Case");
if (caseProperty == null)
{
- throw new DescriptorValidationException(this, "Property " + clrName + "Case not found in " + containingType.GeneratedType);
+ throw new DescriptorValidationException(this, $"Property {clrName}Case not found in {containingType.ClrType}");
}
- var clearMethod = containingType.GeneratedType.GetMethod("Clear" + clrName);
+ var clearMethod = containingType.ClrType.GetMethod("Clear" + clrName);
if (clearMethod == null)
{
- throw new DescriptorValidationException(this, "Method Clear" + clrName + " not found in " + containingType.GeneratedType);
+ throw new DescriptorValidationException(this, $"Method Clear{clrName} not found in {containingType.ClrType}");
}
return new OneofAccessor(caseProperty, clearMethod, this);
diff --git a/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs b/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
new file mode 100644
index 00000000..27f9ab98
--- /dev/null
+++ b/csharp/src/Google.Protobuf/Reflection/OriginalNameAttribute.cs
@@ -0,0 +1,58 @@
+#region Copyright notice and license
+// 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.
+#endregion
+
+using System;
+
+namespace Google.Protobuf.Reflection
+{
+ /// <summary>
+ /// Specifies the original name (in the .proto file) of a named element,
+ /// such as an enum value.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Field)]
+ public class OriginalNameAttribute : Attribute
+ {
+ /// <summary>
+ /// The name of the element in the .proto file.
+ /// </summary>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Constructs a new attribute instance for the given name.
+ /// </summary>
+ /// <param name="name">The name of the element in the .proto file.</param>
+ public OriginalNameAttribute(string name)
+ {
+ Name = ProtoPreconditions.CheckNotNull(name, nameof(name));
+ }
+ }
+} \ No newline at end of file
diff --git a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
index de92fbc1..bbac2173 100644
--- a/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
+++ b/csharp/src/Google.Protobuf/Reflection/SingleFieldAccessor.cs
@@ -61,7 +61,7 @@ namespace Google.Protobuf.Reflection
// TODO: Validate that this is a reasonable single field? (Should be a value type, a message type, or string/ByteString.)
object defaultValue =
- typeof(IMessage).IsAssignableFrom(clrType) ? null
+ descriptor.FieldType == FieldType.Message ? null
: clrType == typeof(string) ? ""
: clrType == typeof(ByteString) ? ByteString.Empty
: Activator.CreateInstance(clrType);
diff --git a/csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs b/csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs
new file mode 100644
index 00000000..e94e3e6c
--- /dev/null
+++ b/csharp/src/Google.Protobuf/Reflection/TypeRegistry.cs
@@ -0,0 +1,183 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 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.
+#endregion
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Google.Protobuf.Reflection
+{
+ /// <summary>
+ /// An immutable registry of types which can be looked up by their full name.
+ /// </summary>
+ public sealed class TypeRegistry
+ {
+ /// <summary>
+ /// An empty type registry, containing no types.
+ /// </summary>
+ public static TypeRegistry Empty { get; } = new TypeRegistry(new Dictionary<string, MessageDescriptor>());
+
+ private readonly Dictionary<string, MessageDescriptor> fullNameToMessageMap;
+
+ private TypeRegistry(Dictionary<string, MessageDescriptor> fullNameToMessageMap)
+ {
+ this.fullNameToMessageMap = fullNameToMessageMap;
+ }
+
+ /// <summary>
+ /// Attempts to find a message descriptor by its full name.
+ /// </summary>
+ /// <param name="fullName">The full name of the message, which is the dot-separated
+ /// combination of package, containing messages and message name</param>
+ /// <returns>The message descriptor corresponding to <paramref name="fullName"/> or null
+ /// if there is no such message descriptor.</returns>
+ public MessageDescriptor Find(string fullName)
+ {
+ MessageDescriptor ret;
+ // Ignore the return value as ret will end up with the right value either way.
+ fullNameToMessageMap.TryGetValue(fullName, out ret);
+ return ret;
+ }
+
+ /// <summary>
+ /// Creates a type registry from the specified set of file descriptors.
+ /// </summary>
+ /// <remarks>
+ /// This is a convenience overload for <see cref="FromFiles(IEnumerable{FileDescriptor})"/>
+ /// to allow calls such as <c>TypeRegistry.FromFiles(descriptor1, descriptor2)</c>.
+ /// </remarks>
+ /// <param name="fileDescriptors">The set of files to include in the registry. Must not contain null values.</param>
+ /// <returns>A type registry for the given files.</returns>
+ public static TypeRegistry FromFiles(params FileDescriptor[] fileDescriptors)
+ {
+ return FromFiles((IEnumerable<FileDescriptor>) fileDescriptors);
+ }
+
+ /// <summary>
+ /// Creates a type registry from the specified set of file descriptors.
+ /// </summary>
+ /// <remarks>
+ /// All message types within all the specified files are added to the registry, and
+ /// the dependencies of the specified files are also added, recursively.
+ /// </remarks>
+ /// <param name="fileDescriptors">The set of files to include in the registry. Must not contain null values.</param>
+ /// <returns>A type registry for the given files.</returns>
+ public static TypeRegistry FromFiles(IEnumerable<FileDescriptor> fileDescriptors)
+ {
+ ProtoPreconditions.CheckNotNull(fileDescriptors, nameof(fileDescriptors));
+ var builder = new Builder();
+ foreach (var file in fileDescriptors)
+ {
+ builder.AddFile(file);
+ }
+ return builder.Build();
+ }
+
+ /// <summary>
+ /// Creates a type registry from the file descriptor parents of the specified set of message descriptors.
+ /// </summary>
+ /// <remarks>
+ /// This is a convenience overload for <see cref="FromMessages(IEnumerable{MessageDescriptor})"/>
+ /// to allow calls such as <c>TypeRegistry.FromFiles(descriptor1, descriptor2)</c>.
+ /// </remarks>
+ /// <param name="messageDescriptors">The set of message descriptors to use to identify file descriptors to include in the registry.
+ /// Must not contain null values.</param>
+ /// <returns>A type registry for the given files.</returns>
+ public static TypeRegistry FromMessages(params MessageDescriptor[] messageDescriptors)
+ {
+ return FromMessages((IEnumerable<MessageDescriptor>) messageDescriptors);
+ }
+
+ /// <summary>
+ /// Creates a type registry from the file descriptor parents of the specified set of message descriptors.
+ /// </summary>
+ /// <remarks>
+ /// The specified message descriptors are only used to identify their file descriptors; the returned registry
+ /// contains all the types within the file descriptors which contain the specified message descriptors (and
+ /// the dependencies of those files), not just the specified messages.
+ /// </remarks>
+ /// <param name="messageDescriptors">The set of message descriptors to use to identify file descriptors to include in the registry.
+ /// Must not contain null values.</param>
+ /// <returns>A type registry for the given files.</returns>
+ public static TypeRegistry FromMessages(IEnumerable<MessageDescriptor> messageDescriptors)
+ {
+ ProtoPreconditions.CheckNotNull(messageDescriptors, nameof(messageDescriptors));
+ return FromFiles(messageDescriptors.Select(md => md.File));
+ }
+
+ /// <summary>
+ /// Builder class which isn't exposed, but acts as a convenient alternative to passing round two dictionaries in recursive calls.
+ /// </summary>
+ private class Builder
+ {
+ private readonly Dictionary<string, MessageDescriptor> types;
+ private readonly HashSet<string> fileDescriptorNames;
+
+ internal Builder()
+ {
+ types = new Dictionary<string, MessageDescriptor>();
+ fileDescriptorNames = new HashSet<string>();
+ }
+
+ internal void AddFile(FileDescriptor fileDescriptor)
+ {
+ if (!fileDescriptorNames.Add(fileDescriptor.Name))
+ {
+ return;
+ }
+ foreach (var dependency in fileDescriptor.Dependencies)
+ {
+ AddFile(dependency);
+ }
+ foreach (var message in fileDescriptor.MessageTypes)
+ {
+ AddMessage(message);
+ }
+ }
+
+ private void AddMessage(MessageDescriptor messageDescriptor)
+ {
+ foreach (var nestedType in messageDescriptor.NestedTypes)
+ {
+ AddMessage(nestedType);
+ }
+ // This will overwrite any previous entry. Given that each file should
+ // only be added once, this could be a problem such as package A.B with type C,
+ // and package A with type B.C... it's unclear what we should do in that case.
+ types[messageDescriptor.FullName] = messageDescriptor;
+ }
+
+ internal TypeRegistry Build()
+ {
+ return new TypeRegistry(types);
+ }
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
index 4a704018..871a383f 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Any.cs
@@ -9,59 +9,90 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/any.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Any {
+ /// <summary>Holder for reflection information generated from google/protobuf/any.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class AnyReflection {
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/any.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static Any() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi",
- "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQksKE2Nv",
- "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAGgAQGiAgNHUEKqAh5Hb29n",
- "bGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Any), new[]{ "TypeUrl", "Value" }, null, null, null)
- }));
- }
- #endregion
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/any.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+ static AnyReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Chlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvEg9nb29nbGUucHJvdG9idWYi",
+ "JgoDQW55EhAKCHR5cGVfdXJsGAEgASgJEg0KBXZhbHVlGAIgASgMQnIKE2Nv",
+ "bS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaJWdpdGh1Yi5jb20vZ29s",
+ "YW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmgAQGiAgNHUEKqAh5Hb29nbGUuUHJv",
+ "dG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Any), global::Google.Protobuf.WellKnownTypes.Any.Parser, new[]{ "TypeUrl", "Value" }, null, null, null)
+ }));
}
+ #endregion
+
}
#region Messages
/// <summary>
- /// `Any` contains an arbitrary serialized message along with a URL
- /// that describes the type of the serialized message.
+ /// `Any` contains an arbitrary serialized protocol buffer message along with a
+ /// URL that describes the type of the serialized message.
+ ///
+ /// Protobuf library provides support to pack/unpack Any values in the form
+ /// of utility functions or additional generated methods of the Any type.
+ ///
+ /// Example 1: Pack and unpack a message in C++.
+ ///
+ /// Foo foo = ...;
+ /// Any any;
+ /// any.PackFrom(foo);
+ /// ...
+ /// if (any.UnpackTo(&amp;foo)) {
+ /// ...
+ /// }
+ ///
+ /// Example 2: Pack and unpack a message in Java.
+ ///
+ /// Foo foo = ...;
+ /// Any any = Any.pack(foo);
+ /// ...
+ /// if (any.is(Foo.class)) {
+ /// foo = any.unpack(Foo.class);
+ /// }
+ ///
+ /// The pack methods provided by protobuf library will by default use
+ /// 'type.googleapis.com/full.type.name' as the type URL and the unpack
+ /// methods only use the fully qualified type name after the last '/'
+ /// in the type URL, for example "foo.bar.com/x/y.z" will yield type
+ /// name "y.z".
+ ///
/// JSON
/// ====
/// The JSON representation of an `Any` value uses the regular
/// representation of the deserialized, embedded message, with an
/// additional field `@type` which contains the type URL. Example:
+ ///
/// package google.profile;
/// message Person {
/// string first_name = 1;
/// string last_name = 2;
/// }
+ ///
/// {
/// "@type": "type.googleapis.com/google.profile.Person",
/// "firstName": &lt;string>,
/// "lastName": &lt;string>
/// }
+ ///
/// If the embedded message type is well-known and has a custom JSON
/// representation, that representation will be embedded adding a field
- /// `value` which holds the custom JSON in addition to the the `@type`
- /// field. Example (for message [google.protobuf.Duration][google.protobuf.Duration]):
+ /// `value` which holds the custom JSON in addition to the `@type`
+ /// field. Example (for message [google.protobuf.Duration][]):
+ ///
/// {
/// "@type": "type.googleapis.com/google.protobuf.Duration",
/// "value": "1.212s"
@@ -73,7 +104,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Any> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Any.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -100,26 +131,31 @@ namespace Google.Protobuf.WellKnownTypes {
private string typeUrl_ = "";
/// <summary>
/// A URL/resource name whose content describes the type of the
- /// serialized message.
+ /// serialized protocol buffer message.
+ ///
/// For URLs which use the schema `http`, `https`, or no schema, the
/// following restrictions and interpretations apply:
+ ///
/// * If no schema is provided, `https` is assumed.
/// * The last segment of the URL's path must represent the fully
/// qualified name of the type (as in `path/google.protobuf.Duration`).
- /// * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
+ /// The name should be in a canonical form (e.g., leading "." is
+ /// not accepted).
+ /// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
/// value in binary format, or produce an error.
/// * Applications are allowed to cache lookup results based on the
/// URL, or have them precompiled into a binary to avoid any
/// lookup. Therefore, binary compatibility needs to be preserved
/// on changes to types. (Use versioned type names to manage
/// breaking changes.)
+ ///
/// Schemas other than `http`, `https` (or the empty schema) might be
/// used with implementation specific semantics.
/// </summary>
public string TypeUrl {
get { return typeUrl_; }
set {
- typeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ typeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -127,12 +163,12 @@ namespace Google.Protobuf.WellKnownTypes {
public const int ValueFieldNumber = 2;
private pb::ByteString value_ = pb::ByteString.Empty;
/// <summary>
- /// Must be valid serialized data of the above specified type.
+ /// Must be a valid serialized protocol buffer of the above specified type.
/// </summary>
public pb::ByteString Value {
get { return value_; }
set {
- value_ = pb::Preconditions.CheckNotNull(value, "value");
+ value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -160,7 +196,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
index 082f7432..f4fac738 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/AnyPartial.cs
@@ -36,11 +36,27 @@ namespace Google.Protobuf.WellKnownTypes
{
public partial class Any
{
+ private const string DefaultPrefix = "type.googleapis.com";
+
// This could be moved to MessageDescriptor if we wanted to, but keeping it here means
// all the Any-specific code is in the same place.
- private static string GetTypeUrl(MessageDescriptor descriptor)
+ private static string GetTypeUrl(MessageDescriptor descriptor, string prefix) =>
+ prefix.EndsWith("/") ? prefix + descriptor.FullName : prefix + "/" + descriptor.FullName;
+
+ /// <summary>
+ /// Retrieves the type name for a type URL. This is always just the last part of the URL,
+ /// after the trailing slash. No validation of anything before the trailing slash is performed.
+ /// If the type URL does not include a slash, an empty string is returned rather than an exception
+ /// being thrown; this won't match any types, and the calling code is probably in a better position
+ /// to give a meaningful error.
+ /// There is no handling of fragments or queries at the moment.
+ /// </summary>
+ /// <param name="typeUrl">The URL to extract the type name from</param>
+ /// <returns>The type name</returns>
+ internal static string GetTypeName(string typeUrl)
{
- return "type.googleapis.com/" + descriptor.FullName;
+ int lastSlash = typeUrl.LastIndexOf('/');
+ return lastSlash == -1 ? "" : typeUrl.Substring(lastSlash + 1);
}
/// <summary>
@@ -55,25 +71,37 @@ namespace Google.Protobuf.WellKnownTypes
// Note: this doesn't perform as well is it might. We could take a MessageParser<T> in an alternative overload,
// which would be expected to perform slightly better... although the difference is likely to be negligible.
T target = new T();
- string targetTypeUrl = GetTypeUrl(target.Descriptor);
- if (TypeUrl != targetTypeUrl)
+ if (GetTypeName(TypeUrl) != target.Descriptor.FullName)
{
- throw new InvalidProtocolBufferException(string.Format("Type url for {0} is {1}; Any message's type url is {2}",
- target.Descriptor.Name, targetTypeUrl, TypeUrl));
+ throw new InvalidProtocolBufferException(
+ $"Full type name for {target.Descriptor.Name} is {target.Descriptor.FullName}; Any message's type url is {TypeUrl}");
}
target.MergeFrom(Value);
return target;
}
/// <summary>
- /// Packs the specified message into an Any message.
+ /// Packs the specified message into an Any message using a type URL prefix of "type.googleapis.com".
+ /// </summary>
+ /// <param name="message">The message to pack.</param>
+ /// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
+ public static Any Pack(IMessage message) => Pack(message, DefaultPrefix);
+
+ /// <summary>
+ /// Packs the specified message into an Any message using the specified type URL prefix.
/// </summary>
/// <param name="message">The message to pack.</param>
+ /// <param name="typeUrlPrefix">The prefix for the type URL.</param>
/// <returns>An Any message with the content and type URL of <paramref name="message"/>.</returns>
- public static Any Pack(IMessage message)
+ public static Any Pack(IMessage message, string typeUrlPrefix)
{
- Preconditions.CheckNotNull(message, "message");
- return new Any { TypeUrl = GetTypeUrl(message.Descriptor), Value = message.ToByteString() };
+ ProtoPreconditions.CheckNotNull(message, nameof(message));
+ ProtoPreconditions.CheckNotNull(typeUrlPrefix, nameof(typeUrlPrefix));
+ return new Any
+ {
+ TypeUrl = GetTypeUrl(message.Descriptor, typeUrlPrefix),
+ Value = message.ToByteString()
+ };
}
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
index 2c64314d..e568a2c9 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Api.cs
@@ -9,49 +9,46 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/api.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Api {
-
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/api.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static Api() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "Chlnb29nbGUvcHJvdG9idWYvYXBpLnByb3RvEg9nb29nbGUucHJvdG9idWYa",
- "JGdvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wcm90bxoaZ29vZ2xl",
- "L3Byb3RvYnVmL3R5cGUucHJvdG8igQIKA0FwaRIMCgRuYW1lGAEgASgJEigK",
- "B21ldGhvZHMYAiADKAsyFy5nb29nbGUucHJvdG9idWYuTWV0aG9kEigKB29w",
- "dGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9uEg8KB3ZlcnNp",
- "b24YBCABKAkSNgoOc291cmNlX2NvbnRleHQYBSABKAsyHi5nb29nbGUucHJv",
- "dG9idWYuU291cmNlQ29udGV4dBImCgZtaXhpbnMYBiADKAsyFi5nb29nbGUu",
- "cHJvdG9idWYuTWl4aW4SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3Rv",
- "YnVmLlN5bnRheCLVAQoGTWV0aG9kEgwKBG5hbWUYASABKAkSGAoQcmVxdWVz",
- "dF90eXBlX3VybBgCIAEoCRIZChFyZXF1ZXN0X3N0cmVhbWluZxgDIAEoCBIZ",
- "ChFyZXNwb25zZV90eXBlX3VybBgEIAEoCRIaChJyZXNwb25zZV9zdHJlYW1p",
- "bmcYBSABKAgSKAoHb3B0aW9ucxgGIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5P",
- "cHRpb24SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3RvYnVmLlN5bnRh",
- "eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCSwoTY29t",
- "Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAaABAaICA0dQQqoCHkdvb2ds",
- "ZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.Proto.SourceContext.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.Type.Descriptor, },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Api), new[]{ "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Method), new[]{ "Name", "RequestTypeUrl", "RequestStreaming", "ResponseTypeUrl", "ResponseStreaming", "Options", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Mixin), new[]{ "Name", "Root" }, null, null, null)
- }));
- }
- #endregion
+ /// <summary>Holder for reflection information generated from google/protobuf/api.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class ApiReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/api.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static ApiReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Chlnb29nbGUvcHJvdG9idWYvYXBpLnByb3RvEg9nb29nbGUucHJvdG9idWYa",
+ "JGdvb2dsZS9wcm90b2J1Zi9zb3VyY2VfY29udGV4dC5wcm90bxoaZ29vZ2xl",
+ "L3Byb3RvYnVmL3R5cGUucHJvdG8igQIKA0FwaRIMCgRuYW1lGAEgASgJEigK",
+ "B21ldGhvZHMYAiADKAsyFy5nb29nbGUucHJvdG9idWYuTWV0aG9kEigKB29w",
+ "dGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9uEg8KB3ZlcnNp",
+ "b24YBCABKAkSNgoOc291cmNlX2NvbnRleHQYBSABKAsyHi5nb29nbGUucHJv",
+ "dG9idWYuU291cmNlQ29udGV4dBImCgZtaXhpbnMYBiADKAsyFi5nb29nbGUu",
+ "cHJvdG9idWYuTWl4aW4SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3Rv",
+ "YnVmLlN5bnRheCLVAQoGTWV0aG9kEgwKBG5hbWUYASABKAkSGAoQcmVxdWVz",
+ "dF90eXBlX3VybBgCIAEoCRIZChFyZXF1ZXN0X3N0cmVhbWluZxgDIAEoCBIZ",
+ "ChFyZXNwb25zZV90eXBlX3VybBgEIAEoCRIaChJyZXNwb25zZV9zdHJlYW1p",
+ "bmcYBSABKAgSKAoHb3B0aW9ucxgGIAMoCzIXLmdvb2dsZS5wcm90b2J1Zi5P",
+ "cHRpb24SJwoGc3ludGF4GAcgASgOMhcuZ29vZ2xlLnByb3RvYnVmLlN5bnRh",
+ "eCIjCgVNaXhpbhIMCgRuYW1lGAEgASgJEgwKBHJvb3QYAiABKAlCSwoTY29t",
+ "Lmdvb2dsZS5wcm90b2J1ZkIIQXBpUHJvdG9QAaABAaICA0dQQqoCHkdvb2ds",
+ "ZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Api), global::Google.Protobuf.WellKnownTypes.Api.Parser, new[]{ "Name", "Methods", "Options", "Version", "SourceContext", "Mixins", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Method), global::Google.Protobuf.WellKnownTypes.Method.Parser, new[]{ "Name", "RequestTypeUrl", "RequestStreaming", "ResponseTypeUrl", "ResponseStreaming", "Options", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Mixin), global::Google.Protobuf.WellKnownTypes.Mixin.Parser, new[]{ "Name", "Root" }, null, null, null)
+ }));
+ }
+ #endregion
- }
}
#region Messages
/// <summary>
@@ -63,7 +60,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Api> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Api.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -100,7 +97,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -139,12 +136,14 @@ namespace Google.Protobuf.WellKnownTypes {
/// outlined below. If the field is not empty, the version in the
/// package name will be verified to be consistent with what is
/// provided here.
+ ///
/// The versioning schema uses [semantic
/// versioning](http://semver.org) where the major version number
/// indicates a breaking change and the minor version an additive,
/// non-breaking change. Both version numbers are signals to users
/// what to expect from different versions, and should be carefully
/// chosen based on the product plan.
+ ///
/// The major version is also reflected in the package name of the
/// API, which must end in `v&lt;major-version>`, as in
/// `google.feature.v1`. For major versions 0 and 1, the suffix can
@@ -154,7 +153,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Version {
get { return version_; }
set {
- version_ = pb::Preconditions.CheckNotNull(value, "value");
+ version_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -186,7 +185,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 7;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax of the service.
/// </summary>
@@ -226,12 +225,12 @@ namespace Google.Protobuf.WellKnownTypes {
if (Version.Length != 0) hash ^= Version.GetHashCode();
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
hash ^= mixins_.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -250,7 +249,7 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteMessage(SourceContext);
}
mixins_.WriteTo(output, _repeated_mixins_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(56);
output.WriteEnum((int) Syntax);
}
@@ -270,7 +269,7 @@ namespace Google.Protobuf.WellKnownTypes {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
}
size += mixins_.CalculateSize(_repeated_mixins_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
@@ -295,7 +294,7 @@ namespace Google.Protobuf.WellKnownTypes {
SourceContext.MergeFrom(other.SourceContext);
}
mixins_.Add(other.mixins_);
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
@@ -353,7 +352,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Method> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Api.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -389,7 +388,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -402,7 +401,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string RequestTypeUrl {
get { return requestTypeUrl_; }
set {
- requestTypeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ requestTypeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -428,7 +427,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string ResponseTypeUrl {
get { return responseTypeUrl_; }
set {
- responseTypeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ responseTypeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -459,7 +458,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 7;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax of this method.
/// </summary>
@@ -499,12 +498,12 @@ namespace Google.Protobuf.WellKnownTypes {
if (ResponseTypeUrl.Length != 0) hash ^= ResponseTypeUrl.GetHashCode();
if (ResponseStreaming != false) hash ^= ResponseStreaming.GetHashCode();
hash ^= options_.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -529,7 +528,7 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteBool(ResponseStreaming);
}
options_.WriteTo(output, _repeated_options_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(56);
output.WriteEnum((int) Syntax);
}
@@ -553,7 +552,7 @@ namespace Google.Protobuf.WellKnownTypes {
size += 1 + 1;
}
size += options_.CalculateSize(_repeated_options_codec);
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
@@ -579,7 +578,7 @@ namespace Google.Protobuf.WellKnownTypes {
ResponseStreaming = other.ResponseStreaming;
}
options_.Add(other.options_);
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
@@ -629,16 +628,21 @@ namespace Google.Protobuf.WellKnownTypes {
/// Declares an API to be included in this API. The including API must
/// redeclare all the methods from the included API, but documentation
/// and options are inherited as follows:
+ ///
/// - If after comment and whitespace stripping, the documentation
/// string of the redeclared method is empty, it will be inherited
/// from the original method.
+ ///
/// - Each annotation belonging to the service config (http,
/// visibility) which is not set in the redeclared method will be
/// inherited.
+ ///
/// - If an http annotation is inherited, the path pattern will be
/// modified as follows. Any version prefix will be replaced by the
/// version of the including API plus the [root][] path if specified.
+ ///
/// Example of a simple mixin:
+ ///
/// package google.acl.v1;
/// service AccessControl {
/// // Get the underlying ACL object.
@@ -646,25 +650,30 @@ namespace Google.Protobuf.WellKnownTypes {
/// option (google.api.http).get = "/v1/{resource=**}:getAcl";
/// }
/// }
+ ///
/// package google.storage.v2;
/// service Storage {
- /// // (-- see AccessControl.GetAcl --)
/// rpc GetAcl(GetAclRequest) returns (Acl);
+ ///
/// // Get a data record.
/// rpc GetData(GetDataRequest) returns (Data) {
/// option (google.api.http).get = "/v2/{resource=**}";
/// }
/// }
+ ///
/// Example of a mixin configuration:
+ ///
/// apis:
/// - name: google.storage.v2.Storage
/// mixins:
/// - name: google.acl.v1.AccessControl
+ ///
/// The mixin construct implies that all methods in `AccessControl` are
/// also declared with same name and request/response types in
/// `Storage`. A documentation generator or annotation processor will
/// see the effective `Storage.GetAcl` method after inherting
/// documentation and annotations as follows:
+ ///
/// service Storage {
/// // Get the underlying ACL object.
/// rpc GetAcl(GetAclRequest) returns (Acl) {
@@ -672,15 +681,20 @@ namespace Google.Protobuf.WellKnownTypes {
/// }
/// ...
/// }
+ ///
/// Note how the version in the path pattern changed from `v1` to `v2`.
+ ///
/// If the `root` field in the mixin is specified, it should be a
/// relative path under which inherited HTTP paths are placed. Example:
+ ///
/// apis:
/// - name: google.storage.v2.Storage
/// mixins:
/// - name: google.acl.v1.AccessControl
/// root: acls
+ ///
/// This implies the following inherited HTTP annotation:
+ ///
/// service Storage {
/// // Get the underlying ACL object.
/// rpc GetAcl(GetAclRequest) returns (Acl) {
@@ -695,7 +709,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Mixin> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Api.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.WellKnownTypes.ApiReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -726,7 +740,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -740,7 +754,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Root {
get { return root_; }
set {
- root_ = pb::Preconditions.CheckNotNull(value, "value");
+ root_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -768,7 +782,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
index 39251e2e..f17358f4 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs
@@ -9,36 +9,34 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/duration.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Duration {
-
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/duration.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static Duration() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "Ch5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8SD2dvb2dsZS5wcm90",
- "b2J1ZiIqCghEdXJhdGlvbhIPCgdzZWNvbmRzGAEgASgDEg0KBW5hbm9zGAIg",
- "ASgFQlAKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAaAB",
- "AaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJv",
- "dG8z"));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Duration), new[]{ "Seconds", "Nanos" }, null, null, null)
- }));
- }
- #endregion
+ /// <summary>Holder for reflection information generated from google/protobuf/duration.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class DurationReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/duration.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static DurationReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Ch5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8SD2dvb2dsZS5wcm90",
+ "b2J1ZiIqCghEdXJhdGlvbhIPCgdzZWNvbmRzGAEgASgDEg0KBW5hbm9zGAIg",
+ "ASgFQnwKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoq",
+ "Z2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9uoAEB",
+ "ogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90",
+ "bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Duration), global::Google.Protobuf.WellKnownTypes.Duration.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
+ }));
+ }
+ #endregion
- }
}
#region Messages
/// <summary>
@@ -48,12 +46,16 @@ namespace Google.Protobuf.WellKnownTypes {
/// or "month". It is related to Timestamp in that the difference between
/// two Timestamp values is a Duration and it can be added or subtracted
/// from a Timestamp. Range is approximately +-10,000 years.
+ ///
/// Example 1: Compute Duration from two Timestamps in pseudo code.
+ ///
/// Timestamp start = ...;
/// Timestamp end = ...;
/// Duration duration = ...;
+ ///
/// duration.seconds = end.seconds - start.seconds;
/// duration.nanos = end.nanos - start.nanos;
+ ///
/// if (duration.seconds &lt; 0 &amp;&amp; duration.nanos > 0) {
/// duration.seconds += 1;
/// duration.nanos -= 1000000000;
@@ -61,12 +63,16 @@ namespace Google.Protobuf.WellKnownTypes {
/// duration.seconds -= 1;
/// duration.nanos += 1000000000;
/// }
+ ///
/// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
+ ///
/// Timestamp start = ...;
/// Duration duration = ...;
/// Timestamp end = ...;
+ ///
/// end.seconds = start.seconds + duration.seconds;
/// end.nanos = start.nanos + duration.nanos;
+ ///
/// if (end.nanos &lt; 0) {
/// end.seconds -= 1;
/// end.nanos += 1000000000;
@@ -81,7 +87,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Duration> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Duration.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -159,7 +165,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
index 18ebefd2..f164bfd1 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/DurationPartial.cs
@@ -31,12 +31,14 @@
#endregion
using System;
+using System.Globalization;
+using System.Text;
namespace Google.Protobuf.WellKnownTypes
{
// Manually-written partial class for the Duration well-known type,
// providing a conversion to TimeSpan and convenience operators.
- public partial class Duration
+ public partial class Duration : ICustomDiagnosticMessage
{
/// <summary>
/// The number of nanoseconds in a second.
@@ -48,14 +50,46 @@ namespace Google.Protobuf.WellKnownTypes
public const int NanosecondsPerTick = 100;
/// <summary>
+ /// The maximum permitted number of seconds.
+ /// </summary>
+ public const long MaxSeconds = 315576000000L;
+
+ /// <summary>
+ /// The minimum permitted number of seconds.
+ /// </summary>
+ public const long MinSeconds = -315576000000L;
+
+ internal const int MaxNanoseconds = NanosecondsPerSecond - 1;
+ internal const int MinNanoseconds = -NanosecondsPerSecond + 1;
+
+ internal static bool IsNormalized(long seconds, int nanoseconds)
+ {
+ // Simple boundaries
+ if (seconds < MinSeconds || seconds > MaxSeconds ||
+ nanoseconds < MinNanoseconds || nanoseconds > MaxNanoseconds)
+ {
+ return false;
+ }
+ // We only have a problem is one is strictly negative and the other is
+ // strictly positive.
+ return Math.Sign(seconds) * Math.Sign(nanoseconds) != -1;
+ }
+
+ /// <summary>
/// Converts this <see cref="Duration"/> to a <see cref="TimeSpan"/>.
/// </summary>
/// <remarks>If the duration is not a precise number of ticks, it is truncated towards 0.</remarks>
/// <returns>The value of this duration, as a <c>TimeSpan</c>.</returns>
+ /// <exception cref="InvalidOperationException">This value isn't a valid normalized duration, as
+ /// described in the documentation.</exception>
public TimeSpan ToTimeSpan()
{
checked
{
+ if (!IsNormalized(Seconds, Nanos))
+ {
+ throw new InvalidOperationException("Duration was not a valid normalized duration");
+ }
long ticks = Seconds * TimeSpan.TicksPerSecond + Nanos / NanosecondsPerTick;
return TimeSpan.FromTicks(ticks);
}
@@ -84,7 +118,7 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The negated value of this duration.</returns>
public static Duration operator -(Duration value)
{
- Preconditions.CheckNotNull(value, "value");
+ ProtoPreconditions.CheckNotNull(value, "value");
checked
{
return Normalize(-value.Seconds, -value.Nanos);
@@ -99,8 +133,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns></returns>
public static Duration operator +(Duration lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds + rhs.Seconds, lhs.Nanos + rhs.Nanos);
@@ -115,8 +149,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The difference between the two specified durations.</returns>
public static Duration operator -(Duration lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@@ -147,5 +181,90 @@ namespace Google.Protobuf.WellKnownTypes
}
return new Duration { Seconds = seconds, Nanos = nanoseconds };
}
+
+ /// <summary>
+ /// Converts a duration specified in seconds/nanoseconds to a string.
+ /// </summary>
+ /// <remarks>
+ /// If the value is a normalized duration in the range described in <c>duration.proto</c>,
+ /// <paramref name="diagnosticOnly"/> is ignored. Otherwise, if the parameter is <c>true</c>,
+ /// a JSON object with a warning is returned; if it is <c>false</c>, an <see cref="InvalidOperationException"/> is thrown.
+ /// </remarks>
+ /// <param name="seconds">Seconds portion of the duration.</param>
+ /// <param name="nanoseconds">Nanoseconds portion of the duration.</param>
+ /// <param name="diagnosticOnly">Determines the handling of non-normalized values</param>
+ /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
+ internal static string ToJson(long seconds, int nanoseconds, bool diagnosticOnly)
+ {
+ if (IsNormalized(seconds, nanoseconds))
+ {
+ var builder = new StringBuilder();
+ builder.Append('"');
+ // The seconds part will normally provide the minus sign if we need it, but not if it's 0...
+ if (seconds == 0 && nanoseconds < 0)
+ {
+ builder.Append('-');
+ }
+
+ builder.Append(seconds.ToString("d", CultureInfo.InvariantCulture));
+ AppendNanoseconds(builder, Math.Abs(nanoseconds));
+ builder.Append("s\"");
+ return builder.ToString();
+ }
+ if (diagnosticOnly)
+ {
+ // Note: the double braces here are escaping for braces in format strings.
+ return string.Format(CultureInfo.InvariantCulture,
+ "{{ \"@warning\": \"Invalid Duration\", \"seconds\": \"{0}\", \"nanos\": {1} }}",
+ seconds,
+ nanoseconds);
+ }
+ else
+ {
+ throw new InvalidOperationException("Non-normalized duration value");
+ }
+ }
+
+ /// <summary>
+ /// Returns a string representation of this <see cref="Duration"/> for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// Normally the returned value will be a JSON string value (including leading and trailing quotes) but
+ /// when the value is non-normalized or out of range, a JSON object representation will be returned
+ /// instead, including a warning. This is to avoid exceptions being thrown when trying to
+ /// diagnose problems - the regular JSON formatter will still throw an exception for non-normalized
+ /// values.
+ /// </remarks>
+ /// <returns>A string representation of this value.</returns>
+ public string ToDiagnosticString()
+ {
+ return ToJson(Seconds, Nanos, true);
+ }
+
+ /// <summary>
+ /// Appends a number of nanoseconds to a StringBuilder. Either 0 digits are added (in which
+ /// case no "." is appended), or 3 6 or 9 digits. This is internal for use in Timestamp as well
+ /// as Duration.
+ /// </summary>
+ internal static void AppendNanoseconds(StringBuilder builder, int nanos)
+ {
+ if (nanos != 0)
+ {
+ builder.Append('.');
+ // Output to 3, 6 or 9 digits.
+ if (nanos % 1000000 == 0)
+ {
+ builder.Append((nanos / 1000000).ToString("d3", CultureInfo.InvariantCulture));
+ }
+ else if (nanos % 1000 == 0)
+ {
+ builder.Append((nanos / 1000).ToString("d6", CultureInfo.InvariantCulture));
+ }
+ else
+ {
+ builder.Append(nanos.ToString("d9", CultureInfo.InvariantCulture));
+ }
+ }
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
index 18223a9e..e08ea240 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs
@@ -9,44 +9,44 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/empty.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Empty {
-
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/empty.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static Empty() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1",
- "ZiIHCgVFbXB0eUJNChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
- "UAGgAQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNi",
- "BnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Empty), null, null, null, null)
- }));
- }
- #endregion
+ /// <summary>Holder for reflection information generated from google/protobuf/empty.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class EmptyReflection {
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/empty.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static EmptyReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Chtnb29nbGUvcHJvdG9idWYvZW1wdHkucHJvdG8SD2dvb2dsZS5wcm90b2J1",
+ "ZiIHCgVFbXB0eUJ5ChNjb20uZ29vZ2xlLnByb3RvYnVmQgpFbXB0eVByb3Rv",
+ "UAFaJ2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9lbXB0eaAB",
+ "AfgBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
+ "cHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Empty), global::Google.Protobuf.WellKnownTypes.Empty.Parser, null, null, null, null)
+ }));
}
+ #endregion
+
}
#region Messages
/// <summary>
/// A generic empty message that you can re-use to avoid defining duplicated
/// empty messages in your APIs. A typical example is to use it as the request
/// or the response type of an API method. For instance:
+ ///
/// service Foo {
/// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
/// }
+ ///
/// The JSON representation for `Empty` is empty JSON object `{}`.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -55,7 +55,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Empty> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Empty.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -95,7 +95,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
index 33c814ef..6f0a64d6 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs
@@ -9,52 +9,55 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/field_mask.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class FieldMask {
+ /// <summary>Holder for reflection information generated from google/protobuf/field_mask.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class FieldMaskReflection {
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/field_mask.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static FieldMask() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "CiBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bxIPZ29vZ2xlLnBy",
- "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUJRChNjb20uZ29v",
- "Z2xlLnByb3RvYnVmQg5GaWVsZE1hc2tQcm90b1ABoAEBogIDR1BCqgIeR29v",
- "Z2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FieldMask), new[]{ "Paths" }, null, null, null)
- }));
- }
- #endregion
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/field_mask.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+ static FieldMaskReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CiBnb29nbGUvcHJvdG9idWYvZmllbGRfbWFzay5wcm90bxIPZ29vZ2xlLnBy",
+ "b3RvYnVmIhoKCUZpZWxkTWFzaxINCgVwYXRocxgBIAMoCUJRChNjb20uZ29v",
+ "Z2xlLnByb3RvYnVmQg5GaWVsZE1hc2tQcm90b1ABoAEBogIDR1BCqgIeR29v",
+ "Z2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FieldMask), global::Google.Protobuf.WellKnownTypes.FieldMask.Parser, new[]{ "Paths" }, null, null, null)
+ }));
}
+ #endregion
+
}
#region Messages
/// <summary>
/// `FieldMask` represents a set of symbolic field paths, for example:
+ ///
/// paths: "f.a"
/// paths: "f.b.d"
+ ///
/// Here `f` represents a field in some root message, `a` and `b`
/// fields in the message found in `f`, and `d` a field found in the
/// message in `f.b`.
+ ///
/// Field masks are used to specify a subset of fields that should be
/// returned by a get operation or modified by an update operation.
/// Field masks also have a custom JSON encoding (see below).
+ ///
/// # Field Masks in Projections
+ ///
/// When used in the context of a projection, a response message or
/// sub-message is filtered by the API to only contain those fields as
/// specified in the mask. For example, if the mask in the previous
/// example is applied to a response message as follows:
+ ///
/// f {
/// a : 22
/// b {
@@ -64,21 +67,26 @@ namespace Google.Protobuf.WellKnownTypes {
/// y : 13
/// }
/// z: 8
+ ///
/// The result will not contain specific values for fields x,y and z
- /// (there value will be set to the default, and omitted in proto text
+ /// (their value will be set to the default, and omitted in proto text
/// output):
+ ///
/// f {
/// a : 22
/// b {
/// d : 1
/// }
/// }
+ ///
/// A repeated field is not allowed except at the last position of a
/// field mask.
+ ///
/// If a FieldMask object is not present in a get operation, the
/// operation applies to all fields (as if a FieldMask of all fields
/// had been specified).
- /// Note that a field mask does not necessarily applies to the
+ ///
+ /// Note that a field mask does not necessarily apply to the
/// top-level response message. In case of a REST get operation, the
/// field mask applies directly to the response, but in case of a REST
/// list operation, the mask instead applies to each individual message
@@ -87,18 +95,22 @@ namespace Google.Protobuf.WellKnownTypes {
/// clearly documented together with its declaration in the API. In
/// any case, the effect on the returned resource/resources is required
/// behavior for APIs.
+ ///
/// # Field Masks in Update Operations
+ ///
/// A field mask in update operations specifies which fields of the
/// targeted resource are going to be updated. The API is required
/// to only change the values of the fields as specified in the mask
/// and leave the others untouched. If a resource is passed in to
/// describe the updated values, the API ignores the values of all
/// fields not covered by the mask.
+ ///
/// In order to reset a field's value to the default, the field must
/// be in the mask and set to the default value in the provided resource.
/// Hence, in order to reset all fields of a resource, provide a default
/// instance of the resource and set all fields in the mask, or do
/// not provide a mask as described below.
+ ///
/// If a field mask is not present on update, the operation applies to
/// all fields (as if a field mask of all fields has been specified).
/// Note that in the presence of schema evolution, this may mean that
@@ -106,19 +118,26 @@ namespace Google.Protobuf.WellKnownTypes {
/// the request will be reset to their default. If this is unwanted
/// behavior, a specific service may require a client to always specify
/// a field mask, producing an error if not.
+ ///
/// As with get operations, the location of the resource which
/// describes the updated values in the request message depends on the
/// operation kind. In any case, the effect of the field mask is
/// required to be honored by the API.
+ ///
/// ## Considerations for HTTP REST
+ ///
/// The HTTP kind of an update operation which uses a field mask must
/// be set to PATCH instead of PUT in order to satisfy HTTP semantics
/// (PUT must only be used for full updates).
+ ///
/// # JSON Encoding of Field Masks
+ ///
/// In JSON, a field mask is encoded as a single string where paths are
/// separated by a comma. Fields name in each path are converted
/// to/from lower-camel naming conventions.
+ ///
/// As an example, consider the following message declarations:
+ ///
/// message Profile {
/// User user = 1;
/// Photo photo = 2;
@@ -127,15 +146,46 @@ namespace Google.Protobuf.WellKnownTypes {
/// string display_name = 1;
/// string address = 2;
/// }
+ ///
/// In proto a field mask for `Profile` may look as such:
+ ///
/// mask {
/// paths: "user.display_name"
/// paths: "photo"
/// }
+ ///
/// In JSON, the same mask is represented as below:
+ ///
/// {
/// mask: "user.displayName,photo"
/// }
+ ///
+ /// # Field Masks and Oneof Fields
+ ///
+ /// Field masks treat fields in oneofs just as regular fields. Consider the
+ /// following message:
+ ///
+ /// message SampleMessage {
+ /// oneof test_oneof {
+ /// string name = 4;
+ /// SubMessage sub_message = 9;
+ /// }
+ /// }
+ ///
+ /// The field mask can be:
+ ///
+ /// mask {
+ /// paths: "name"
+ /// }
+ ///
+ /// Or:
+ ///
+ /// mask {
+ /// paths: "sub_message"
+ /// }
+ ///
+ /// Note that oneof type names ("test_oneof" in this case) cannot be used in
+ /// paths.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class FieldMask : pb::IMessage<FieldMask> {
@@ -143,7 +193,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<FieldMask> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.FieldMask.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.FieldMaskReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -198,7 +248,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
new file mode 100644
index 00000000..4bd62cf3
--- /dev/null
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/FieldMaskPartial.cs
@@ -0,0 +1,123 @@
+#region Copyright notice and license
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 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.
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ // Manually-written partial class for the FieldMask well-known type.
+ public partial class FieldMask : ICustomDiagnosticMessage
+ {
+ /// <summary>
+ /// Converts a timestamp specified in seconds/nanoseconds to a string.
+ /// </summary>
+ /// <remarks>
+ /// If the value is a normalized duration in the range described in <c>field_mask.proto</c>,
+ /// <paramref name="diagnosticOnly"/> is ignored. Otherwise, if the parameter is <c>true</c>,
+ /// a JSON object with a warning is returned; if it is <c>false</c>, an <see cref="InvalidOperationException"/> is thrown.
+ /// </remarks>
+ /// <param name="paths">Paths in the field mask</param>
+ /// <param name="diagnosticOnly">Determines the handling of non-normalized values</param>
+ /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
+ internal static string ToJson(IList<string> paths, bool diagnosticOnly)
+ {
+ var firstInvalid = paths.FirstOrDefault(p => !ValidatePath(p));
+ if (firstInvalid == null)
+ {
+ var writer = new StringWriter();
+ JsonFormatter.WriteString(writer, string.Join(",", paths.Select(JsonFormatter.ToCamelCase)));
+ return writer.ToString();
+ }
+ else
+ {
+ if (diagnosticOnly)
+ {
+ var writer = new StringWriter();
+ writer.Write("{ \"@warning\": \"Invalid FieldMask\", \"paths\": ");
+ JsonFormatter.Default.WriteList(writer, (IList)paths);
+ writer.Write(" }");
+ return writer.ToString();
+ }
+ else
+ {
+ throw new InvalidOperationException($"Invalid field mask to be converted to JSON: {firstInvalid}");
+ }
+ }
+ }
+
+ /// <summary>
+ /// Camel-case converter with added strictness for field mask formatting.
+ /// </summary>
+ /// <exception cref="InvalidOperationException">The field mask is invalid for JSON representation</exception>
+ private static bool ValidatePath(string input)
+ {
+ for (int i = 0; i < input.Length; i++)
+ {
+ char c = input[i];
+ if (c >= 'A' && c <= 'Z')
+ {
+ return false;
+ }
+ if (c == '_' && i < input.Length - 1)
+ {
+ char next = input[i + 1];
+ if (next < 'a' || next > 'z')
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Returns a string representation of this <see cref="FieldMask"/> for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// Normally the returned value will be a JSON string value (including leading and trailing quotes) but
+ /// when the value is non-normalized or out of range, a JSON object representation will be returned
+ /// instead, including a warning. This is to avoid exceptions being thrown when trying to
+ /// diagnose problems - the regular JSON formatter will still throw an exception for non-normalized
+ /// values.
+ /// </remarks>
+ /// <returns>A string representation of this value.</returns>
+ public string ToDiagnosticString()
+ {
+ return ToJson(Paths, true);
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
index d87c54bd..a235ecef 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs
@@ -9,36 +9,33 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/source_context.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class SourceContext {
-
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/source_context.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static SourceContext() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "CiRnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8SD2dvb2ds",
- "ZS5wcm90b2J1ZiIiCg1Tb3VyY2VDb250ZXh0EhEKCWZpbGVfbmFtZRgBIAEo",
- "CUJVChNjb20uZ29vZ2xlLnByb3RvYnVmQhJTb3VyY2VDb250ZXh0UHJvdG9Q",
- "AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
- "cHJvdG8z"));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.SourceContext), new[]{ "FileName" }, null, null, null)
- }));
- }
- #endregion
+ /// <summary>Holder for reflection information generated from google/protobuf/source_context.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class SourceContextReflection {
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/source_context.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static SourceContextReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CiRnb29nbGUvcHJvdG9idWYvc291cmNlX2NvbnRleHQucHJvdG8SD2dvb2ds",
+ "ZS5wcm90b2J1ZiIiCg1Tb3VyY2VDb250ZXh0EhEKCWZpbGVfbmFtZRgBIAEo",
+ "CUJVChNjb20uZ29vZ2xlLnByb3RvYnVmQhJTb3VyY2VDb250ZXh0UHJvdG9Q",
+ "AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
+ "cHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.SourceContext), global::Google.Protobuf.WellKnownTypes.SourceContext.Parser, new[]{ "FileName" }, null, null, null)
+ }));
}
+ #endregion
+
}
#region Messages
/// <summary>
@@ -51,7 +48,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<SourceContext> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.SourceContext.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -82,7 +79,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string FileName {
get { return fileName_; }
set {
- fileName_ = pb::Preconditions.CheckNotNull(value, "value");
+ fileName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -108,7 +105,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
index a9961bea..edc8940d 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs
@@ -9,59 +9,58 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/struct.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Struct {
-
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/struct.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static Struct() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "Chxnb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvEg9nb29nbGUucHJvdG9i",
- "dWYihAEKBlN0cnVjdBIzCgZmaWVsZHMYASADKAsyIy5nb29nbGUucHJvdG9i",
- "dWYuU3RydWN0LkZpZWxkc0VudHJ5GkUKC0ZpZWxkc0VudHJ5EgsKA2tleRgB",
- "IAEoCRIlCgV2YWx1ZRgCIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZToC",
- "OAEi6gEKBVZhbHVlEjAKCm51bGxfdmFsdWUYASABKA4yGi5nb29nbGUucHJv",
- "dG9idWYuTnVsbFZhbHVlSAASFgoMbnVtYmVyX3ZhbHVlGAIgASgBSAASFgoM",
- "c3RyaW5nX3ZhbHVlGAMgASgJSAASFAoKYm9vbF92YWx1ZRgEIAEoCEgAEi8K",
- "DHN0cnVjdF92YWx1ZRgFIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RI",
- "ABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RW",
- "YWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIW",
- "Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W",
- "QUxVRRAAQk4KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAGg",
- "AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnBy",
- "b3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), new[]{ "Fields" }, null, null, new pbr::GeneratedCodeInfo[] { null, }),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Value), new[]{ "NullValue", "NumberValue", "StringValue", "BoolValue", "StructValue", "ListValue" }, new[]{ "Kind" }, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.ListValue), new[]{ "Values" }, null, null, null)
- }));
- }
- #endregion
+ /// <summary>Holder for reflection information generated from google/protobuf/struct.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class StructReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/struct.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static StructReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Chxnb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvEg9nb29nbGUucHJvdG9i",
+ "dWYihAEKBlN0cnVjdBIzCgZmaWVsZHMYASADKAsyIy5nb29nbGUucHJvdG9i",
+ "dWYuU3RydWN0LkZpZWxkc0VudHJ5GkUKC0ZpZWxkc0VudHJ5EgsKA2tleRgB",
+ "IAEoCRIlCgV2YWx1ZRgCIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZToC",
+ "OAEi6gEKBVZhbHVlEjAKCm51bGxfdmFsdWUYASABKA4yGi5nb29nbGUucHJv",
+ "dG9idWYuTnVsbFZhbHVlSAASFgoMbnVtYmVyX3ZhbHVlGAIgASgBSAASFgoM",
+ "c3RyaW5nX3ZhbHVlGAMgASgJSAASFAoKYm9vbF92YWx1ZRgEIAEoCEgAEi8K",
+ "DHN0cnVjdF92YWx1ZRgFIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RI",
+ "ABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RW",
+ "YWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIW",
+ "Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W",
+ "QUxVRRAAQoEBChNjb20uZ29vZ2xlLnByb3RvYnVmQgtTdHJ1Y3RQcm90b1AB",
+ "WjFnaXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wdHlwZXMvc3RydWN0O3N0",
+ "cnVjdHBioAEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5",
+ "cGVzYgZwcm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), global::Google.Protobuf.WellKnownTypes.Struct.Parser, new[]{ "Fields" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Value), global::Google.Protobuf.WellKnownTypes.Value.Parser, new[]{ "NullValue", "NumberValue", "StringValue", "BoolValue", "StructValue", "ListValue" }, new[]{ "Kind" }, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.ListValue), global::Google.Protobuf.WellKnownTypes.ListValue.Parser, new[]{ "Values" }, null, null, null)
+ }));
+ }
+ #endregion
- }
}
#region Enums
/// <summary>
/// `NullValue` is a singleton enumeration to represent the null value for the
/// `Value` type union.
+ ///
/// The JSON representation for `NullValue` is JSON `null`.
/// </summary>
public enum NullValue {
/// <summary>
/// Null value.
/// </summary>
- NULL_VALUE = 0,
+ [pbr::OriginalName("NULL_VALUE")] NullValue = 0,
}
#endregion
@@ -74,6 +73,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// scripting languages like JS a struct is represented as an
/// object. The details of that representation are described together
/// with the proto support for the language.
+ ///
/// The JSON representation for `Struct` is JSON object.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -82,7 +82,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Struct> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Struct.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -109,7 +109,7 @@ namespace Google.Protobuf.WellKnownTypes {
= new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Value.Parser), 10);
private readonly pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> fields_ = new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>();
/// <summary>
- /// Map of dynamically typed values.
+ /// Unordered map of dynamically typed values.
/// </summary>
public pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> Fields {
get { return fields_; }
@@ -137,7 +137,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -179,6 +179,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// null, a number, a string, a boolean, a recursive struct value, or a
/// list of values. A producer of value is expected to set one of that
/// variants, absence of any variant indicates an error.
+ ///
/// The JSON representation for `Value` is JSON value.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -187,7 +188,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Value> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Struct.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -234,7 +235,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// Represents a null value.
/// </summary>
public global::Google.Protobuf.WellKnownTypes.NullValue NullValue {
- get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : global::Google.Protobuf.WellKnownTypes.NullValue.NULL_VALUE; }
+ get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : 0; }
set {
kind_ = value;
kindCase_ = KindOneofCase.NullValue;
@@ -262,7 +263,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string StringValue {
get { return kindCase_ == KindOneofCase.StringValue ? (string) kind_ : ""; }
set {
- kind_ = pb::Preconditions.CheckNotNull(value, "value");
+ kind_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
kindCase_ = KindOneofCase.StringValue;
}
}
@@ -344,6 +345,7 @@ namespace Google.Protobuf.WellKnownTypes {
if (BoolValue != other.BoolValue) return false;
if (!object.Equals(StructValue, other.StructValue)) return false;
if (!object.Equals(ListValue, other.ListValue)) return false;
+ if (KindCase != other.KindCase) return false;
return true;
}
@@ -355,11 +357,12 @@ namespace Google.Protobuf.WellKnownTypes {
if (kindCase_ == KindOneofCase.BoolValue) hash ^= BoolValue.GetHashCode();
if (kindCase_ == KindOneofCase.StructValue) hash ^= StructValue.GetHashCode();
if (kindCase_ == KindOneofCase.ListValue) hash ^= ListValue.GetHashCode();
+ hash ^= (int) kindCase_;
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -489,6 +492,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// `ListValue` is a wrapper around a repeated field of values.
+ ///
/// The JSON representation for `ListValue` is JSON array.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -497,7 +501,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<ListValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Struct.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.WellKnownTypes.StructReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -552,7 +556,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
index f372f8fd..053b88bd 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs
@@ -9,36 +9,34 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/timestamp.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Timestamp {
-
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/timestamp.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static Timestamp() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv",
- "dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY",
- "AiABKAVCUQoTY29tLmdvb2dsZS5wcm90b2J1ZkIOVGltZXN0YW1wUHJvdG9Q",
- "AaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IG",
- "cHJvdG8z"));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Timestamp), new[]{ "Seconds", "Nanos" }, null, null, null)
- }));
- }
- #endregion
+ /// <summary>Holder for reflection information generated from google/protobuf/timestamp.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class TimestampReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/timestamp.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static TimestampReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Ch9nb29nbGUvcHJvdG9idWYvdGltZXN0YW1wLnByb3RvEg9nb29nbGUucHJv",
+ "dG9idWYiKwoJVGltZXN0YW1wEg8KB3NlY29uZHMYASABKAMSDQoFbmFub3MY",
+ "AiABKAVCgQEKE2NvbS5nb29nbGUucHJvdG9idWZCDlRpbWVzdGFtcFByb3Rv",
+ "UAFaK2dpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy90aW1lc3Rh",
+ "bXCgAQH4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlw",
+ "ZXNiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Timestamp), global::Google.Protobuf.WellKnownTypes.Timestamp.Parser, new[]{ "Seconds", "Nanos" }, null, null, null)
+ }));
+ }
+ #endregion
- }
}
#region Messages
/// <summary>
@@ -53,30 +51,43 @@ namespace Google.Protobuf.WellKnownTypes {
/// By restricting to that range, we ensure that we can convert to
/// and from RFC 3339 date strings.
/// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
+ ///
/// Example 1: Compute Timestamp from POSIX `time()`.
+ ///
/// Timestamp timestamp;
/// timestamp.set_seconds(time(NULL));
/// timestamp.set_nanos(0);
+ ///
/// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
+ ///
/// struct timeval tv;
/// gettimeofday(&amp;tv, NULL);
+ ///
/// Timestamp timestamp;
/// timestamp.set_seconds(tv.tv_sec);
/// timestamp.set_nanos(tv.tv_usec * 1000);
+ ///
/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
+ ///
/// FILETIME ft;
/// GetSystemTimeAsFileTime(&amp;ft);
/// UINT64 ticks = (((UINT64)ft.dwHighDateTime) &lt;&lt; 32) | ft.dwLowDateTime;
+ ///
/// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
/// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
/// Timestamp timestamp;
/// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
/// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
+ ///
/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
+ ///
/// long millis = System.currentTimeMillis();
+ ///
/// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
/// .setNanos((int) ((millis % 1000) * 1000000)).build();
+ ///
/// Example 5: Compute Timestamp from current time in Python.
+ ///
/// now = time.time()
/// seconds = int(now)
/// nanos = int((now - seconds) * 10**9)
@@ -88,7 +99,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Timestamp> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Timestamp.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.TimestampReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -165,7 +176,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
index 68584358..aa403473 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/TimestampPartial.cs
@@ -31,13 +31,25 @@
#endregion
using System;
+using System.Globalization;
+using System.Text;
namespace Google.Protobuf.WellKnownTypes
{
- public partial class Timestamp
+ public partial class Timestamp : ICustomDiagnosticMessage
{
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- private static readonly long BclSecondsAtUnixEpoch = UnixEpoch.Ticks / TimeSpan.TicksPerSecond;
+ // Constants determined programmatically, but then hard-coded so they can be constant expressions.
+ private const long BclSecondsAtUnixEpoch = 62135596800;
+ internal const long UnixSecondsAtBclMaxValue = 253402300799;
+ internal const long UnixSecondsAtBclMinValue = -BclSecondsAtUnixEpoch;
+ internal const int MaxNanos = Duration.NanosecondsPerSecond - 1;
+
+ private static bool IsNormalized(long seconds, int nanoseconds) =>
+ nanoseconds >= 0 &&
+ nanoseconds <= MaxNanos &&
+ seconds >= UnixSecondsAtBclMinValue &&
+ seconds <= UnixSecondsAtBclMaxValue;
/// <summary>
/// Returns the difference between one <see cref="Timestamp"/> and another, as a <see cref="Duration"/>.
@@ -47,8 +59,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The difference between the two specified timestamps.</returns>
public static Duration operator -(Timestamp lhs, Timestamp rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Duration.Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@@ -63,8 +75,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The result of adding the duration to the timestamp.</returns>
public static Timestamp operator +(Timestamp lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds + rhs.Seconds, lhs.Nanos + rhs.Nanos);
@@ -79,8 +91,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <returns>The result of subtracting the duration from the timestamp.</returns>
public static Timestamp operator -(Timestamp lhs, Duration rhs)
{
- Preconditions.CheckNotNull(lhs, "lhs");
- Preconditions.CheckNotNull(rhs, "rhs");
+ ProtoPreconditions.CheckNotNull(lhs, "lhs");
+ ProtoPreconditions.CheckNotNull(rhs, "rhs");
checked
{
return Normalize(lhs.Seconds - rhs.Seconds, lhs.Nanos - rhs.Nanos);
@@ -97,8 +109,14 @@ namespace Google.Protobuf.WellKnownTypes
/// <see cref="DateTime"/> value precisely on a second.
/// </remarks>
/// <returns>This timestamp as a <c>DateTime</c>.</returns>
+ /// <exception cref="InvalidOperationException">The timestamp contains invalid values; either it is
+ /// incorrectly normalized or is outside the valid range.</exception>
public DateTime ToDateTime()
{
+ if (!IsNormalized(Seconds, Nanos))
+ {
+ throw new InvalidOperationException(@"Timestamp contains invalid values: Seconds={Seconds}; Nanos={Nanos}");
+ }
return UnixEpoch.AddSeconds(Seconds).AddTicks(Nanos / Duration.NanosecondsPerTick);
}
@@ -112,6 +130,8 @@ namespace Google.Protobuf.WellKnownTypes
/// <see cref="DateTimeOffset"/> value precisely on a second.
/// </remarks>
/// <returns>This timestamp as a <c>DateTimeOffset</c>.</returns>
+ /// <exception cref="InvalidOperationException">The timestamp contains invalid values; either it is
+ /// incorrectly normalized or is outside the valid range.</exception>
public DateTimeOffset ToDateTimeOffset()
{
return new DateTimeOffset(ToDateTime(), TimeSpan.Zero);
@@ -163,5 +183,59 @@ namespace Google.Protobuf.WellKnownTypes
}
return new Timestamp { Seconds = seconds, Nanos = nanoseconds };
}
+
+ /// <summary>
+ /// Converts a timestamp specified in seconds/nanoseconds to a string.
+ /// </summary>
+ /// <remarks>
+ /// If the value is a normalized duration in the range described in <c>timestamp.proto</c>,
+ /// <paramref name="diagnosticOnly"/> is ignored. Otherwise, if the parameter is <c>true</c>,
+ /// a JSON object with a warning is returned; if it is <c>false</c>, an <see cref="InvalidOperationException"/> is thrown.
+ /// </remarks>
+ /// <param name="seconds">Seconds portion of the duration.</param>
+ /// <param name="nanoseconds">Nanoseconds portion of the duration.</param>
+ /// <param name="diagnosticOnly">Determines the handling of non-normalized values</param>
+ /// <exception cref="InvalidOperationException">The represented duration is invalid, and <paramref name="diagnosticOnly"/> is <c>false</c>.</exception>
+ internal static string ToJson(long seconds, int nanoseconds, bool diagnosticOnly)
+ {
+ if (IsNormalized(seconds, nanoseconds))
+ {
+ // Use .NET's formatting for the value down to the second, including an opening double quote (as it's a string value)
+ DateTime dateTime = UnixEpoch.AddSeconds(seconds);
+ var builder = new StringBuilder();
+ builder.Append('"');
+ builder.Append(dateTime.ToString("yyyy'-'MM'-'dd'T'HH:mm:ss", CultureInfo.InvariantCulture));
+ Duration.AppendNanoseconds(builder, nanoseconds);
+ builder.Append("Z\"");
+ return builder.ToString();
+ }
+ if (diagnosticOnly)
+ {
+ return string.Format(CultureInfo.InvariantCulture,
+ "{{ \"@warning\": \"Invalid Timestamp\", \"seconds\": \"{0}\", \"nanos\": {1} }}",
+ seconds,
+ nanoseconds);
+ }
+ else
+ {
+ throw new InvalidOperationException("Non-normalized timestamp value");
+ }
+ }
+
+ /// <summary>
+ /// Returns a string representation of this <see cref="Timestamp"/> for diagnostic purposes.
+ /// </summary>
+ /// <remarks>
+ /// Normally the returned value will be a JSON string value (including leading and trailing quotes) but
+ /// when the value is non-normalized or out of range, a JSON object representation will be returned
+ /// instead, including a warning. This is to avoid exceptions being thrown when trying to
+ /// diagnose problems - the regular JSON formatter will still throw an exception for non-normalized
+ /// values.
+ /// </remarks>
+ /// <returns>A string representation of this value.</returns>
+ public string ToDiagnosticString()
+ {
+ return ToJson(Seconds, Nanos, true);
+ }
}
}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
index 3be90853..657c2464 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Type.cs
@@ -9,90 +9,88 @@ using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {
- namespace Proto {
-
- /// <summary>Holder for reflection information generated from google/protobuf/type.proto</summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Type {
-
- #region Descriptor
- /// <summary>File descriptor for google/protobuf/type.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static Type() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "Chpnb29nbGUvcHJvdG9idWYvdHlwZS5wcm90bxIPZ29vZ2xlLnByb3RvYnVm",
- "Ghlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvGiRnb29nbGUvcHJvdG9idWYv",
- "c291cmNlX2NvbnRleHQucHJvdG8i1wEKBFR5cGUSDAoEbmFtZRgBIAEoCRIm",
- "CgZmaWVsZHMYAiADKAsyFi5nb29nbGUucHJvdG9idWYuRmllbGQSDgoGb25l",
- "b2ZzGAMgAygJEigKB29wdGlvbnMYBCADKAsyFy5nb29nbGUucHJvdG9idWYu",
- "T3B0aW9uEjYKDnNvdXJjZV9jb250ZXh0GAUgASgLMh4uZ29vZ2xlLnByb3Rv",
- "YnVmLlNvdXJjZUNvbnRleHQSJwoGc3ludGF4GAYgASgOMhcuZ29vZ2xlLnBy",
- "b3RvYnVmLlN5bnRheCK+BQoFRmllbGQSKQoEa2luZBgBIAEoDjIbLmdvb2ds",
- "ZS5wcm90b2J1Zi5GaWVsZC5LaW5kEjcKC2NhcmRpbmFsaXR5GAIgASgOMiIu",
- "Z29vZ2xlLnByb3RvYnVmLkZpZWxkLkNhcmRpbmFsaXR5Eg4KBm51bWJlchgD",
- "IAEoBRIMCgRuYW1lGAQgASgJEhAKCHR5cGVfdXJsGAYgASgJEhMKC29uZW9m",
- "X2luZGV4GAcgASgFEg4KBnBhY2tlZBgIIAEoCBIoCgdvcHRpb25zGAkgAygL",
- "MhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhIRCglqc29uX25hbWUYCiABKAki",
- "yAIKBEtpbmQSEAoMVFlQRV9VTktOT1dOEAASDwoLVFlQRV9ET1VCTEUQARIO",
- "CgpUWVBFX0ZMT0FUEAISDgoKVFlQRV9JTlQ2NBADEg8KC1RZUEVfVUlOVDY0",
- "EAQSDgoKVFlQRV9JTlQzMhAFEhAKDFRZUEVfRklYRUQ2NBAGEhAKDFRZUEVf",
- "RklYRUQzMhAHEg0KCVRZUEVfQk9PTBAIEg8KC1RZUEVfU1RSSU5HEAkSDgoK",
- "VFlQRV9HUk9VUBAKEhAKDFRZUEVfTUVTU0FHRRALEg4KClRZUEVfQllURVMQ",
- "DBIPCgtUWVBFX1VJTlQzMhANEg0KCVRZUEVfRU5VTRAOEhEKDVRZUEVfU0ZJ",
- "WEVEMzIQDxIRCg1UWVBFX1NGSVhFRDY0EBASDwoLVFlQRV9TSU5UMzIQERIP",
- "CgtUWVBFX1NJTlQ2NBASInQKC0NhcmRpbmFsaXR5EhcKE0NBUkRJTkFMSVRZ",
- "X1VOS05PV04QABIYChRDQVJESU5BTElUWV9PUFRJT05BTBABEhgKFENBUkRJ",
- "TkFMSVRZX1JFUVVJUkVEEAISGAoUQ0FSRElOQUxJVFlfUkVQRUFURUQQAyLO",
- "AQoERW51bRIMCgRuYW1lGAEgASgJEi0KCWVudW12YWx1ZRgCIAMoCzIaLmdv",
- "b2dsZS5wcm90b2J1Zi5FbnVtVmFsdWUSKAoHb3B0aW9ucxgDIAMoCzIXLmdv",
- "b2dsZS5wcm90b2J1Zi5PcHRpb24SNgoOc291cmNlX2NvbnRleHQYBCABKAsy",
- "Hi5nb29nbGUucHJvdG9idWYuU291cmNlQ29udGV4dBInCgZzeW50YXgYBSAB",
- "KA4yFy5nb29nbGUucHJvdG9idWYuU3ludGF4IlMKCUVudW1WYWx1ZRIMCgRu",
- "YW1lGAEgASgJEg4KBm51bWJlchgCIAEoBRIoCgdvcHRpb25zGAMgAygLMhcu",
- "Z29vZ2xlLnByb3RvYnVmLk9wdGlvbiI7CgZPcHRpb24SDAoEbmFtZRgBIAEo",
- "CRIjCgV2YWx1ZRgCIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkqLgoGU3lu",
- "dGF4EhEKDVNZTlRBWF9QUk9UTzIQABIRCg1TWU5UQVhfUFJPVE8zEAFCTAoT",
- "Y29tLmdvb2dsZS5wcm90b2J1ZkIJVHlwZVByb3RvUAGgAQGiAgNHUEKqAh5H",
- "b29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
- new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.Proto.Any.Descriptor, global::Google.Protobuf.WellKnownTypes.Proto.SourceContext.Descriptor, },
- new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Enum), new[]{ "Name", "Enumvalue", "Options", "SourceContext", "Syntax" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.EnumValue), new[]{ "Name", "Number", "Options" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Option), new[]{ "Name", "Value" }, null, null, null)
- }));
- }
- #endregion
-
+ /// <summary>Holder for reflection information generated from google/protobuf/type.proto</summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ public static partial class TypeReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for google/protobuf/type.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static TypeReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "Chpnb29nbGUvcHJvdG9idWYvdHlwZS5wcm90bxIPZ29vZ2xlLnByb3RvYnVm",
+ "Ghlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvGiRnb29nbGUvcHJvdG9idWYv",
+ "c291cmNlX2NvbnRleHQucHJvdG8i1wEKBFR5cGUSDAoEbmFtZRgBIAEoCRIm",
+ "CgZmaWVsZHMYAiADKAsyFi5nb29nbGUucHJvdG9idWYuRmllbGQSDgoGb25l",
+ "b2ZzGAMgAygJEigKB29wdGlvbnMYBCADKAsyFy5nb29nbGUucHJvdG9idWYu",
+ "T3B0aW9uEjYKDnNvdXJjZV9jb250ZXh0GAUgASgLMh4uZ29vZ2xlLnByb3Rv",
+ "YnVmLlNvdXJjZUNvbnRleHQSJwoGc3ludGF4GAYgASgOMhcuZ29vZ2xlLnBy",
+ "b3RvYnVmLlN5bnRheCLVBQoFRmllbGQSKQoEa2luZBgBIAEoDjIbLmdvb2ds",
+ "ZS5wcm90b2J1Zi5GaWVsZC5LaW5kEjcKC2NhcmRpbmFsaXR5GAIgASgOMiIu",
+ "Z29vZ2xlLnByb3RvYnVmLkZpZWxkLkNhcmRpbmFsaXR5Eg4KBm51bWJlchgD",
+ "IAEoBRIMCgRuYW1lGAQgASgJEhAKCHR5cGVfdXJsGAYgASgJEhMKC29uZW9m",
+ "X2luZGV4GAcgASgFEg4KBnBhY2tlZBgIIAEoCBIoCgdvcHRpb25zGAkgAygL",
+ "MhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhIRCglqc29uX25hbWUYCiABKAkS",
+ "FQoNZGVmYXVsdF92YWx1ZRgLIAEoCSLIAgoES2luZBIQCgxUWVBFX1VOS05P",
+ "V04QABIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBF",
+ "X0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoM",
+ "VFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09M",
+ "EAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9N",
+ "RVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJ",
+ "VFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVE",
+ "NjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIidAoLQ2Fy",
+ "ZGluYWxpdHkSFwoTQ0FSRElOQUxJVFlfVU5LTk9XThAAEhgKFENBUkRJTkFM",
+ "SVRZX09QVElPTkFMEAESGAoUQ0FSRElOQUxJVFlfUkVRVUlSRUQQAhIYChRD",
+ "QVJESU5BTElUWV9SRVBFQVRFRBADIs4BCgRFbnVtEgwKBG5hbWUYASABKAkS",
+ "LQoJZW51bXZhbHVlGAIgAygLMhouZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1",
+ "ZRIoCgdvcHRpb25zGAMgAygLMhcuZ29vZ2xlLnByb3RvYnVmLk9wdGlvbhI2",
+ "Cg5zb3VyY2VfY29udGV4dBgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5Tb3Vy",
+ "Y2VDb250ZXh0EicKBnN5bnRheBgFIAEoDjIXLmdvb2dsZS5wcm90b2J1Zi5T",
+ "eW50YXgiUwoJRW51bVZhbHVlEgwKBG5hbWUYASABKAkSDgoGbnVtYmVyGAIg",
+ "ASgFEigKB29wdGlvbnMYAyADKAsyFy5nb29nbGUucHJvdG9idWYuT3B0aW9u",
+ "IjsKBk9wdGlvbhIMCgRuYW1lGAEgASgJEiMKBXZhbHVlGAIgASgLMhQuZ29v",
+ "Z2xlLnByb3RvYnVmLkFueSouCgZTeW50YXgSEQoNU1lOVEFYX1BST1RPMhAA",
+ "EhEKDVNZTlRBWF9QUk9UTzMQAUJMChNjb20uZ29vZ2xlLnByb3RvYnVmQglU",
+ "eXBlUHJvdG9QAaABAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25v",
+ "d25UeXBlc2IGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.AnyReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.SourceContextReflection.Descriptor, },
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.Syntax), }, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Type), global::Google.Protobuf.WellKnownTypes.Type.Parser, new[]{ "Name", "Fields", "Oneofs", "Options", "SourceContext", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Field), global::Google.Protobuf.WellKnownTypes.Field.Parser, new[]{ "Kind", "Cardinality", "Number", "Name", "TypeUrl", "OneofIndex", "Packed", "Options", "JsonName", "DefaultValue" }, null, new[]{ typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Kind), typeof(global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality) }, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Enum), global::Google.Protobuf.WellKnownTypes.Enum.Parser, new[]{ "Name", "Enumvalue", "Options", "SourceContext", "Syntax" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.EnumValue), global::Google.Protobuf.WellKnownTypes.EnumValue.Parser, new[]{ "Name", "Number", "Options" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Option), global::Google.Protobuf.WellKnownTypes.Option.Parser, new[]{ "Name", "Value" }, null, null, null)
+ }));
}
+ #endregion
+
}
#region Enums
/// <summary>
- /// Syntax specifies the syntax in which a service element was defined.
+ /// The syntax in which a protocol buffer element is defined.
/// </summary>
public enum Syntax {
/// <summary>
- /// Syntax "proto2"
+ /// Syntax `proto2`.
/// </summary>
- SYNTAX_PROTO2 = 0,
+ [pbr::OriginalName("SYNTAX_PROTO2")] Proto2 = 0,
/// <summary>
- /// Syntax "proto3"
+ /// Syntax `proto3`.
/// </summary>
- SYNTAX_PROTO3 = 1,
+ [pbr::OriginalName("SYNTAX_PROTO3")] Proto3 = 1,
}
#endregion
#region Messages
/// <summary>
- /// A light-weight descriptor for a proto message type.
+ /// A protocol buffer message type.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Type : pb::IMessage<Type> {
@@ -100,7 +98,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Type> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Type.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -135,7 +133,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -157,7 +155,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForString(26);
private readonly pbc::RepeatedField<string> oneofs_ = new pbc::RepeatedField<string>();
/// <summary>
- /// The list of oneof definitions.
+ /// The list of types appearing in `oneof` definitions in this type.
/// </summary>
public pbc::RepeatedField<string> Oneofs {
get { return oneofs_; }
@@ -169,7 +167,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(34, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// The proto options.
+ /// The protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -190,7 +188,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 6;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax.
/// </summary>
@@ -228,12 +226,12 @@ namespace Google.Protobuf.WellKnownTypes {
hash ^= oneofs_.GetHashCode();
hash ^= options_.GetHashCode();
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -248,7 +246,7 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteRawTag(42);
output.WriteMessage(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(48);
output.WriteEnum((int) Syntax);
}
@@ -265,7 +263,7 @@ namespace Google.Protobuf.WellKnownTypes {
if (sourceContext_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
@@ -287,7 +285,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
SourceContext.MergeFrom(other.SourceContext);
}
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
@@ -333,7 +331,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
/// <summary>
- /// Field represents a single field of a message type.
+ /// A single field of a message type.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Field : pb::IMessage<Field> {
@@ -341,7 +339,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Field> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Type.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -364,6 +362,7 @@ namespace Google.Protobuf.WellKnownTypes {
packed_ = other.packed_;
options_ = other.options_.Clone();
jsonName_ = other.jsonName_;
+ defaultValue_ = other.defaultValue_;
}
public Field Clone() {
@@ -372,9 +371,9 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "kind" field.</summary>
public const int KindFieldNumber = 1;
- private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN;
+ private global::Google.Protobuf.WellKnownTypes.Field.Types.Kind kind_ = 0;
/// <summary>
- /// The field kind.
+ /// The field type.
/// </summary>
public global::Google.Protobuf.WellKnownTypes.Field.Types.Kind Kind {
get { return kind_; }
@@ -385,9 +384,9 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "cardinality" field.</summary>
public const int CardinalityFieldNumber = 2;
- private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN;
+ private global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality cardinality_ = 0;
/// <summary>
- /// The field cardinality, i.e. optional/required/repeated.
+ /// The field cardinality.
/// </summary>
public global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality Cardinality {
get { return cardinality_; }
@@ -400,7 +399,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int NumberFieldNumber = 3;
private int number_;
/// <summary>
- /// The proto field number.
+ /// The field number.
/// </summary>
public int Number {
get { return number_; }
@@ -418,7 +417,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -426,13 +425,13 @@ namespace Google.Protobuf.WellKnownTypes {
public const int TypeUrlFieldNumber = 6;
private string typeUrl_ = "";
/// <summary>
- /// The type URL (without the scheme) when the type is MESSAGE or ENUM,
- /// such as `type.googleapis.com/google.protobuf.Empty`.
+ /// The field type URL, without the scheme, for message or enumeration
+ /// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
/// </summary>
public string TypeUrl {
get { return typeUrl_; }
set {
- typeUrl_ = pb::Preconditions.CheckNotNull(value, "value");
+ typeUrl_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -440,7 +439,8 @@ namespace Google.Protobuf.WellKnownTypes {
public const int OneofIndexFieldNumber = 7;
private int oneofIndex_;
/// <summary>
- /// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
+ /// The index of the field type in `Type.oneofs`, for message or enumeration
+ /// types. The first type has index 1; zero means the type is not in the list.
/// </summary>
public int OneofIndex {
get { return oneofIndex_; }
@@ -468,7 +468,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(74, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// The proto options.
+ /// The protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -478,12 +478,25 @@ namespace Google.Protobuf.WellKnownTypes {
public const int JsonNameFieldNumber = 10;
private string jsonName_ = "";
/// <summary>
- /// The JSON name for this field.
+ /// The field JSON name.
/// </summary>
public string JsonName {
get { return jsonName_; }
set {
- jsonName_ = pb::Preconditions.CheckNotNull(value, "value");
+ jsonName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "default_value" field.</summary>
+ public const int DefaultValueFieldNumber = 11;
+ private string defaultValue_ = "";
+ /// <summary>
+ /// The string value of the default value of this field. Proto2 syntax only.
+ /// </summary>
+ public string DefaultValue {
+ get { return defaultValue_; }
+ set {
+ defaultValue_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -507,13 +520,14 @@ namespace Google.Protobuf.WellKnownTypes {
if (Packed != other.Packed) return false;
if(!options_.Equals(other.options_)) return false;
if (JsonName != other.JsonName) return false;
+ if (DefaultValue != other.DefaultValue) return false;
return true;
}
public override int GetHashCode() {
int hash = 1;
- if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) hash ^= Kind.GetHashCode();
- if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) hash ^= Cardinality.GetHashCode();
+ if (Kind != 0) hash ^= Kind.GetHashCode();
+ if (Cardinality != 0) hash ^= Cardinality.GetHashCode();
if (Number != 0) hash ^= Number.GetHashCode();
if (Name.Length != 0) hash ^= Name.GetHashCode();
if (TypeUrl.Length != 0) hash ^= TypeUrl.GetHashCode();
@@ -521,19 +535,20 @@ namespace Google.Protobuf.WellKnownTypes {
if (Packed != false) hash ^= Packed.GetHashCode();
hash ^= options_.GetHashCode();
if (JsonName.Length != 0) hash ^= JsonName.GetHashCode();
+ if (DefaultValue.Length != 0) hash ^= DefaultValue.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
- if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
+ if (Kind != 0) {
output.WriteRawTag(8);
output.WriteEnum((int) Kind);
}
- if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
+ if (Cardinality != 0) {
output.WriteRawTag(16);
output.WriteEnum((int) Cardinality);
}
@@ -562,14 +577,18 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteRawTag(82);
output.WriteString(JsonName);
}
+ if (DefaultValue.Length != 0) {
+ output.WriteRawTag(90);
+ output.WriteString(DefaultValue);
+ }
}
public int CalculateSize() {
int size = 0;
- if (Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
+ if (Kind != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Kind);
}
- if (Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
+ if (Cardinality != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Cardinality);
}
if (Number != 0) {
@@ -591,6 +610,9 @@ namespace Google.Protobuf.WellKnownTypes {
if (JsonName.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(JsonName);
}
+ if (DefaultValue.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(DefaultValue);
+ }
return size;
}
@@ -598,10 +620,10 @@ namespace Google.Protobuf.WellKnownTypes {
if (other == null) {
return;
}
- if (other.Kind != global::Google.Protobuf.WellKnownTypes.Field.Types.Kind.TYPE_UNKNOWN) {
+ if (other.Kind != 0) {
Kind = other.Kind;
}
- if (other.Cardinality != global::Google.Protobuf.WellKnownTypes.Field.Types.Cardinality.CARDINALITY_UNKNOWN) {
+ if (other.Cardinality != 0) {
Cardinality = other.Cardinality;
}
if (other.Number != 0) {
@@ -623,6 +645,9 @@ namespace Google.Protobuf.WellKnownTypes {
if (other.JsonName.Length != 0) {
JsonName = other.JsonName;
}
+ if (other.DefaultValue.Length != 0) {
+ DefaultValue = other.DefaultValue;
+ }
}
public void MergeFrom(pb::CodedInputStream input) {
@@ -668,6 +693,10 @@ namespace Google.Protobuf.WellKnownTypes {
JsonName = input.ReadString();
break;
}
+ case 90: {
+ DefaultValue = input.ReadString();
+ break;
+ }
}
}
}
@@ -677,108 +706,107 @@ namespace Google.Protobuf.WellKnownTypes {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class Types {
/// <summary>
- /// Kind represents a basic field type.
+ /// Basic field types.
/// </summary>
public enum Kind {
/// <summary>
/// Field type unknown.
/// </summary>
- TYPE_UNKNOWN = 0,
+ [pbr::OriginalName("TYPE_UNKNOWN")] TypeUnknown = 0,
/// <summary>
/// Field type double.
/// </summary>
- TYPE_DOUBLE = 1,
+ [pbr::OriginalName("TYPE_DOUBLE")] TypeDouble = 1,
/// <summary>
/// Field type float.
/// </summary>
- TYPE_FLOAT = 2,
+ [pbr::OriginalName("TYPE_FLOAT")] TypeFloat = 2,
/// <summary>
/// Field type int64.
/// </summary>
- TYPE_INT64 = 3,
+ [pbr::OriginalName("TYPE_INT64")] TypeInt64 = 3,
/// <summary>
/// Field type uint64.
/// </summary>
- TYPE_UINT64 = 4,
+ [pbr::OriginalName("TYPE_UINT64")] TypeUint64 = 4,
/// <summary>
/// Field type int32.
/// </summary>
- TYPE_INT32 = 5,
+ [pbr::OriginalName("TYPE_INT32")] TypeInt32 = 5,
/// <summary>
/// Field type fixed64.
/// </summary>
- TYPE_FIXED64 = 6,
+ [pbr::OriginalName("TYPE_FIXED64")] TypeFixed64 = 6,
/// <summary>
/// Field type fixed32.
/// </summary>
- TYPE_FIXED32 = 7,
+ [pbr::OriginalName("TYPE_FIXED32")] TypeFixed32 = 7,
/// <summary>
/// Field type bool.
/// </summary>
- TYPE_BOOL = 8,
+ [pbr::OriginalName("TYPE_BOOL")] TypeBool = 8,
/// <summary>
/// Field type string.
/// </summary>
- TYPE_STRING = 9,
+ [pbr::OriginalName("TYPE_STRING")] TypeString = 9,
/// <summary>
- /// Field type group (deprecated proto2 type)
+ /// Field type group. Proto2 syntax only, and deprecated.
/// </summary>
- TYPE_GROUP = 10,
+ [pbr::OriginalName("TYPE_GROUP")] TypeGroup = 10,
/// <summary>
/// Field type message.
/// </summary>
- TYPE_MESSAGE = 11,
+ [pbr::OriginalName("TYPE_MESSAGE")] TypeMessage = 11,
/// <summary>
/// Field type bytes.
/// </summary>
- TYPE_BYTES = 12,
+ [pbr::OriginalName("TYPE_BYTES")] TypeBytes = 12,
/// <summary>
/// Field type uint32.
/// </summary>
- TYPE_UINT32 = 13,
+ [pbr::OriginalName("TYPE_UINT32")] TypeUint32 = 13,
/// <summary>
/// Field type enum.
/// </summary>
- TYPE_ENUM = 14,
+ [pbr::OriginalName("TYPE_ENUM")] TypeEnum = 14,
/// <summary>
/// Field type sfixed32.
/// </summary>
- TYPE_SFIXED32 = 15,
+ [pbr::OriginalName("TYPE_SFIXED32")] TypeSfixed32 = 15,
/// <summary>
/// Field type sfixed64.
/// </summary>
- TYPE_SFIXED64 = 16,
+ [pbr::OriginalName("TYPE_SFIXED64")] TypeSfixed64 = 16,
/// <summary>
/// Field type sint32.
/// </summary>
- TYPE_SINT32 = 17,
+ [pbr::OriginalName("TYPE_SINT32")] TypeSint32 = 17,
/// <summary>
/// Field type sint64.
/// </summary>
- TYPE_SINT64 = 18,
+ [pbr::OriginalName("TYPE_SINT64")] TypeSint64 = 18,
}
/// <summary>
- /// Cardinality represents whether a field is optional, required, or
- /// repeated.
+ /// Whether a field is optional, required, or repeated.
/// </summary>
public enum Cardinality {
/// <summary>
- /// The field cardinality is unknown. Typically an error condition.
+ /// For fields with unknown cardinality.
/// </summary>
- CARDINALITY_UNKNOWN = 0,
+ [pbr::OriginalName("CARDINALITY_UNKNOWN")] Unknown = 0,
/// <summary>
/// For optional fields.
/// </summary>
- CARDINALITY_OPTIONAL = 1,
+ [pbr::OriginalName("CARDINALITY_OPTIONAL")] Optional = 1,
/// <summary>
- /// For required fields. Not used for proto3.
+ /// For required fields. Proto2 syntax only.
/// </summary>
- CARDINALITY_REQUIRED = 2,
+ [pbr::OriginalName("CARDINALITY_REQUIRED")] Required = 2,
/// <summary>
/// For repeated fields.
/// </summary>
- CARDINALITY_REPEATED = 3,
+ [pbr::OriginalName("CARDINALITY_REPEATED")] Repeated = 3,
}
}
@@ -795,7 +823,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Enum> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Type.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -829,7 +857,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -851,7 +879,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// Proto options for the enum type.
+ /// Protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -872,7 +900,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Field number for the "syntax" field.</summary>
public const int SyntaxFieldNumber = 5;
- private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2;
+ private global::Google.Protobuf.WellKnownTypes.Syntax syntax_ = 0;
/// <summary>
/// The source syntax.
/// </summary>
@@ -908,12 +936,12 @@ namespace Google.Protobuf.WellKnownTypes {
hash ^= enumvalue_.GetHashCode();
hash ^= options_.GetHashCode();
if (sourceContext_ != null) hash ^= SourceContext.GetHashCode();
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) hash ^= Syntax.GetHashCode();
+ if (Syntax != 0) hash ^= Syntax.GetHashCode();
return hash;
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -927,7 +955,7 @@ namespace Google.Protobuf.WellKnownTypes {
output.WriteRawTag(34);
output.WriteMessage(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
output.WriteRawTag(40);
output.WriteEnum((int) Syntax);
}
@@ -943,7 +971,7 @@ namespace Google.Protobuf.WellKnownTypes {
if (sourceContext_ != null) {
size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceContext);
}
- if (Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (Syntax != 0) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Syntax);
}
return size;
@@ -964,7 +992,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
SourceContext.MergeFrom(other.SourceContext);
}
- if (other.Syntax != global::Google.Protobuf.WellKnownTypes.Syntax.SYNTAX_PROTO2) {
+ if (other.Syntax != 0) {
Syntax = other.Syntax;
}
}
@@ -1014,7 +1042,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<EnumValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Type.Descriptor.MessageTypes[3]; }
+ get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1046,7 +1074,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1069,7 +1097,7 @@ namespace Google.Protobuf.WellKnownTypes {
= pb::FieldCodec.ForMessage(26, global::Google.Protobuf.WellKnownTypes.Option.Parser);
private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> options_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option>();
/// <summary>
- /// Proto options for the enum value.
+ /// Protocol buffer options.
/// </summary>
public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Option> Options {
get { return options_; }
@@ -1101,7 +1129,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -1167,7 +1195,8 @@ namespace Google.Protobuf.WellKnownTypes {
}
/// <summary>
- /// Proto option attached to messages/fields/enums etc.
+ /// A protocol buffer option, which can be attached to a message, field,
+ /// enumeration, etc.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Option : pb::IMessage<Option> {
@@ -1175,7 +1204,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Option> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Proto.Type.Descriptor.MessageTypes[4]; }
+ get { return global::Google.Protobuf.WellKnownTypes.TypeReflection.Descriptor.MessageTypes[4]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -1201,12 +1230,12 @@ namespace Google.Protobuf.WellKnownTypes {
public const int NameFieldNumber = 1;
private string name_ = "";
/// <summary>
- /// Proto option name.
+ /// The option's name. For example, `"java_package"`.
/// </summary>
public string Name {
get { return name_; }
set {
- name_ = pb::Preconditions.CheckNotNull(value, "value");
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -1214,7 +1243,7 @@ namespace Google.Protobuf.WellKnownTypes {
public const int ValueFieldNumber = 2;
private global::Google.Protobuf.WellKnownTypes.Any value_;
/// <summary>
- /// Proto option value.
+ /// The option's value. For example, `"com.google.protobuf"`.
/// </summary>
public global::Google.Protobuf.WellKnownTypes.Any Value {
get { return value_; }
@@ -1247,7 +1276,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs
new file mode 100644
index 00000000..d34b560d
--- /dev/null
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/ValuePartial.cs
@@ -0,0 +1,99 @@
+#region Copyright notice and license
+// 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.
+#endregion
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ public partial class Value
+ {
+ /// <summary>
+ /// Convenience method to create a Value message with a string value.
+ /// </summary>
+ /// <param name="value">Value to set for the StringValue property.</param>
+ /// <returns>A newly-created Value message with the given value.</returns>
+ public static Value ForString(string value)
+ {
+ ProtoPreconditions.CheckNotNull(value, "value");
+ return new Value { StringValue = value };
+ }
+
+ /// <summary>
+ /// Convenience method to create a Value message with a number value.
+ /// </summary>
+ /// <param name="value">Value to set for the NumberValue property.</param>
+ /// <returns>A newly-created Value message with the given value.</returns>
+ public static Value ForNumber(double value)
+ {
+ return new Value { NumberValue = value };
+ }
+
+ /// <summary>
+ /// Convenience method to create a Value message with a Boolean value.
+ /// </summary>
+ /// <param name="value">Value to set for the BoolValue property.</param>
+ /// <returns>A newly-created Value message with the given value.</returns>
+ public static Value ForBool(bool value)
+ {
+ return new Value { BoolValue = value };
+ }
+
+ /// <summary>
+ /// Convenience method to create a Value message with a null initial value.
+ /// </summary>
+ /// <returns>A newly-created Value message a null initial value.</returns>
+ public static Value ForNull()
+ {
+ return new Value { NullValue = 0 };
+ }
+
+ /// <summary>
+ /// Convenience method to create a Value message with an initial list of values.
+ /// </summary>
+ /// <remarks>The values provided are not cloned; the references are copied directly.</remarks>
+ /// <returns>A newly-created Value message an initial list value.</returns>
+ public static Value ForList(params Value[] values)
+ {
+ ProtoPreconditions.CheckNotNull(values, "values");
+ return new Value { ListValue = new ListValue { Values = { values } } };
+ }
+
+ /// <summary>
+ /// Convenience method to create a Value message with an initial struct value
+ /// </summary>
+ /// <remarks>The value provided is not cloned; the reference is copied directly.</remarks>
+ /// <returns>A newly-created Value message an initial struct value.</returns>
+ public static Value ForStruct(Struct value)
+ {
+ ProtoPreconditions.CheckNotNull(value, "value");
+ return new Value { StructValue = value };
+ }
+ }
+}
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
index d26395f8..c8867d0e 100644
--- a/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs
@@ -11,7 +11,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>Holder for reflection information generated from google/protobuf/wrappers.proto</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- public static partial class Wrappers {
+ public static partial class WrappersReflection {
#region Descriptor
/// <summary>File descriptor for google/protobuf/wrappers.proto</summary>
@@ -20,7 +20,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
private static pbr::FileDescriptor descriptor;
- static Wrappers() {
+ static WrappersReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Ch5nb29nbGUvcHJvdG9idWYvd3JhcHBlcnMucHJvdG8SD2dvb2dsZS5wcm90",
@@ -29,21 +29,22 @@ namespace Google.Protobuf.WellKnownTypes {
"KAMiHAoLVUludDY0VmFsdWUSDQoFdmFsdWUYASABKAQiGwoKSW50MzJWYWx1",
"ZRINCgV2YWx1ZRgBIAEoBSIcCgtVSW50MzJWYWx1ZRINCgV2YWx1ZRgBIAEo",
"DSIaCglCb29sVmFsdWUSDQoFdmFsdWUYASABKAgiHAoLU3RyaW5nVmFsdWUS",
- "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJQ",
- "ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAGgAQGiAgNH",
- "UEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+ "DQoFdmFsdWUYASABKAkiGwoKQnl0ZXNWYWx1ZRINCgV2YWx1ZRgBIAEoDEJ/",
+ "ChNjb20uZ29vZ2xlLnByb3RvYnVmQg1XcmFwcGVyc1Byb3RvUAFaKmdpdGh1",
+ "Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy93cmFwcGVyc6ABAfgBAaIC",
+ "A0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc2IGcHJvdG8z"));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.DoubleValue), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FloatValue), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int64Value), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt64Value), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int32Value), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt32Value), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BoolValue), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.StringValue), new[]{ "Value" }, null, null, null),
- new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BytesValue), new[]{ "Value" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.DoubleValue), global::Google.Protobuf.WellKnownTypes.DoubleValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.FloatValue), global::Google.Protobuf.WellKnownTypes.FloatValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int64Value), global::Google.Protobuf.WellKnownTypes.Int64Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt64Value), global::Google.Protobuf.WellKnownTypes.UInt64Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Int32Value), global::Google.Protobuf.WellKnownTypes.Int32Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.UInt32Value), global::Google.Protobuf.WellKnownTypes.UInt32Value.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BoolValue), global::Google.Protobuf.WellKnownTypes.BoolValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.StringValue), global::Google.Protobuf.WellKnownTypes.StringValue.Parser, new[]{ "Value" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.WellKnownTypes.BytesValue), global::Google.Protobuf.WellKnownTypes.BytesValue.Parser, new[]{ "Value" }, null, null, null)
}));
}
#endregion
@@ -52,6 +53,7 @@ namespace Google.Protobuf.WellKnownTypes {
#region Messages
/// <summary>
/// Wrapper message for `double`.
+ ///
/// The JSON representation for `DoubleValue` is JSON number.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -60,7 +62,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<DoubleValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[0]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[0]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -116,7 +118,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -162,6 +164,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `float`.
+ ///
/// The JSON representation for `FloatValue` is JSON number.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -170,7 +173,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<FloatValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[1]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[1]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -226,7 +229,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -272,6 +275,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `int64`.
+ ///
/// The JSON representation for `Int64Value` is JSON string.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -280,7 +284,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Int64Value> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[2]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[2]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -336,7 +340,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -382,6 +386,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `uint64`.
+ ///
/// The JSON representation for `UInt64Value` is JSON string.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -390,7 +395,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<UInt64Value> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[3]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[3]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -446,7 +451,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -492,6 +497,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `int32`.
+ ///
/// The JSON representation for `Int32Value` is JSON number.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -500,7 +506,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<Int32Value> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[4]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[4]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -556,7 +562,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -602,6 +608,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `uint32`.
+ ///
/// The JSON representation for `UInt32Value` is JSON number.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -610,7 +617,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<UInt32Value> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[5]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[5]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -666,7 +673,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -712,6 +719,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `bool`.
+ ///
/// The JSON representation for `BoolValue` is JSON `true` and `false`.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -720,7 +728,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<BoolValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[6]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[6]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -776,7 +784,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -822,6 +830,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `string`.
+ ///
/// The JSON representation for `StringValue` is JSON string.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -830,7 +839,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<StringValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[7]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[7]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -860,7 +869,7 @@ namespace Google.Protobuf.WellKnownTypes {
public string Value {
get { return value_; }
set {
- value_ = pb::Preconditions.CheckNotNull(value, "value");
+ value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -886,7 +895,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
@@ -932,6 +941,7 @@ namespace Google.Protobuf.WellKnownTypes {
/// <summary>
/// Wrapper message for `bytes`.
+ ///
/// The JSON representation for `BytesValue` is JSON string.
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -940,7 +950,7 @@ namespace Google.Protobuf.WellKnownTypes {
public static pb::MessageParser<BytesValue> Parser { get { return _parser; } }
public static pbr::MessageDescriptor Descriptor {
- get { return global::Google.Protobuf.WellKnownTypes.Wrappers.Descriptor.MessageTypes[8]; }
+ get { return global::Google.Protobuf.WellKnownTypes.WrappersReflection.Descriptor.MessageTypes[8]; }
}
pbr::MessageDescriptor pb::IMessage.Descriptor {
@@ -970,7 +980,7 @@ namespace Google.Protobuf.WellKnownTypes {
public pb::ByteString Value {
get { return value_; }
set {
- value_ = pb::Preconditions.CheckNotNull(value, "value");
+ value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
@@ -996,7 +1006,7 @@ namespace Google.Protobuf.WellKnownTypes {
}
public override string ToString() {
- return pb::JsonFormatter.Default.Format(this);
+ return pb::JsonFormatter.ToDiagnosticString(this);
}
public void WriteTo(pb::CodedOutputStream output) {
diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs b/csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs
new file mode 100644
index 00000000..9f620eb4
--- /dev/null
+++ b/csharp/src/Google.Protobuf/WellKnownTypes/WrappersPartial.cs
@@ -0,0 +1,42 @@
+#region Copyright notice and license
+// 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.
+#endregion
+
+namespace Google.Protobuf.WellKnownTypes
+{
+ public static partial class WrappersReflection
+ {
+ /// <summary>
+ /// Field number for the single "value" field in all wrapper types.
+ /// </summary>
+ internal const int WrapperValueFieldNumber = Int32Value.ValueFieldNumber;
+ }
+}
diff --git a/csharp/src/Google.Protobuf/packages.config b/csharp/src/Google.Protobuf/packages.config
new file mode 100644
index 00000000..40b8fd92
--- /dev/null
+++ b/csharp/src/Google.Protobuf/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="NuSpec.ReferenceGenerator" version="1.4.1" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" />
+</packages> \ No newline at end of file