public void TestFieldPresenceReflection() { MessageDescriptor descriptor = TestAllTypes.Descriptor; FieldDescriptor optionalInt32Field = descriptor.FindFieldByName("optional_int32"); FieldDescriptor optionalStringField = descriptor.FindFieldByName("optional_string"); FieldDescriptor optionalBytesField = descriptor.FindFieldByName("optional_bytes"); FieldDescriptor optionalNestedEnumField = descriptor.FindFieldByName("optional_nested_enum"); TestAllTypes message = TestAllTypes.CreateBuilder().Build(); Assert.IsFalse(message.HasField(optionalInt32Field)); Assert.IsFalse(message.HasField(optionalStringField)); Assert.IsFalse(message.HasField(optionalBytesField)); Assert.IsFalse(message.HasField(optionalNestedEnumField)); // Set to default value is seen as not present message = TestAllTypes.CreateBuilder() .SetOptionalInt32(0) .SetOptionalString("") .SetOptionalBytes(ByteString.Empty) .SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.FOO) .Build(); Assert.IsFalse(message.HasField(optionalInt32Field)); Assert.IsFalse(message.HasField(optionalStringField)); Assert.IsFalse(message.HasField(optionalBytesField)); Assert.IsFalse(message.HasField(optionalNestedEnumField)); Assert.AreEqual(0, message.AllFields.Count); // Set t0 non-defalut value is seen as present message = TestAllTypes.CreateBuilder() .SetOptionalInt32(1) .SetOptionalString("x") .SetOptionalBytes(ByteString.CopyFromUtf8("y")) .SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.BAR) .Build(); Assert.IsTrue(message.HasField(optionalInt32Field)); Assert.IsTrue(message.HasField(optionalStringField)); Assert.IsTrue(message.HasField(optionalBytesField)); Assert.IsTrue(message.HasField(optionalNestedEnumField)); Assert.AreEqual(4, message.AllFields.Count); }