plutoo / protobuf-csharp-port

Automatically exported from code.google.com/p/protobuf-csharp-port
Other
0 stars 0 forks source link

Extensions problems while deserialize #58

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.
// test.proto
package test;

message TestMsg {
    extensions 100 to max;
    required string str1 = 1;
}

message TestMsgAdd {
    extend TestMsg {
        required TestMsgAdd data = 100;
    }
    required string str2 = 1;
}
2.
//Program.cs
//...main()...
            test.TestMsgAdd tma = new test.TestMsgAdd.Builder().SetStr2("str2").Build();
            test.TestMsg tm = new test.TestMsg.Builder().SetStr1("str1")
                                                        .SetExtension(test.TestMsgAdd.Data, tma).Build();
            bool succ = tm.HasExtension(test.TestMsgAdd.Data); // TRUE
            Console.WriteLine(succ); // 15
            Console.WriteLine(tm.SerializedSize);
            byte[] buff = tm.ToByteArray();
            test.TestMsg copy = test.TestMsg.ParseFrom(buff);
            succ = copy.HasExtension(test.TestMsgAdd.Data);
            Console.WriteLine(succ); // FALSE (SHOULD BE TRUE)
            Console.WriteLine(copy.SerializedSize); // 15

What is the expected output? What do you see instead?
Expected Output:
TRUE
15
TRUE
15

I see instead:
TRUE
15
FALSE
15

What version of the product are you using? On what operating system?
protobuf-csharp-port-2.4.1.521-release-binaries.zip
VS2010, .Net4, Win7x64 SP1

Please provide any additional information below.
Looks like the library doesn't work good with extensions. Thanks.

Original issue reported on code.google.com by anthony....@gmail.com on 28 May 2013 at 7:11

GoogleCodeExporter commented 9 years ago
The problem is that you are not providing an extension registry.  You can still 
access via the UnknownFields collection, or by providing an extension registry:

    private static void Main()
    {
        TestMsgAdd tma = new TestMsgAdd.Builder().SetStr2("str2").Build();
        TestMsg tm = new TestMsg.Builder().SetStr1("str1")
                                                    .SetExtension(TestMsgAdd.Data, tma).Build();
        bool succ = tm.HasExtension(TestMsgAdd.Data); // TRUE
        Assert.IsTrue(succ); // 15
        Assert.AreEqual(15, tm.SerializedSize);
        byte[] buff = tm.ToByteArray();
        Assert.AreEqual(15, buff.Length);

        TestMsg copy = TestMsg.ParseFrom(buff);
        Assert.IsFalse(copy.HasExtension(TestMsgAdd.Data)); // Extension is unknown at time of deserialize
        Assert.AreEqual(15, copy.SerializedSize);

        // However, we can still access this via unkonwn fields:
        UnknownField field;
        Assert.IsTrue(copy.UnknownFields.FieldDictionary.TryGetValue(TestMsgAdd.Data.Number, out field));
        var tmaCopy = TestMsgAdd.ParseFrom(field.LengthDelimitedList[0]);
        Assert.AreEqual(tma, tmaCopy);

        // Alternatively, when we deserialize we must provide an extension registry with the required extension
        var registry = ExtensionRegistry.CreateInstance();
        registry.Add(TestMsgAdd.Data);
        copy = TestMsg.ParseFrom(buff, registry);
        Assert.IsTrue(copy.HasExtension(TestMsgAdd.Data));
        tmaCopy = copy.GetExtension(TestMsgAdd.Data);
        Assert.AreEqual(tma, tmaCopy);

        Console.WriteLine("Success!");
        Console.ReadLine();
    }

**NOTE: The UnknownFields collection is not available in the LITE_RUNTIME 
optimization.  You must use the extension registry in this case.

Original comment by Grig...@gmail.com on 20 Jul 2013 at 5:21