mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-12-16 11:37:18 +00:00
* Replace protobuf 2.6.1 with 3.21.8 * Update/add protobuf libs * Add CS2 protos * Remove old csgo/dota protos * Add versioned protoc bin * Comment out Valve's `schema` define for now * Use ENetworkDisconnectionReason * Fix-up `offsetof` to avoid errors on some Clang versions
296 lines
12 KiB
C#
296 lines
12 KiB
C#
#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;
|
|
using Google.Protobuf.Reflection;
|
|
using System.Buffers;
|
|
using pb = global::Google.Protobuf;
|
|
using pbr = global::Google.Protobuf.Reflection;
|
|
using NUnit.Framework;
|
|
using System.IO;
|
|
using System;
|
|
using Google.Protobuf.Buffers;
|
|
|
|
namespace Google.Protobuf
|
|
{
|
|
public class LegacyGeneratedCodeTest
|
|
{
|
|
[Test]
|
|
public void IntermixingOfNewAndLegacyGeneratedCodeWorksWithCodedInputStream()
|
|
{
|
|
var message = new ParseContextEnabledMessageB
|
|
{
|
|
A = new LegacyGeneratedCodeMessageA
|
|
{
|
|
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
|
|
},
|
|
OptionalInt32 = 6789
|
|
};
|
|
var data = message.ToByteArray();
|
|
|
|
// when parsing started using CodedInputStream and a message with legacy generated code
|
|
// is encountered somewhere in the parse tree, we still need to be able to use its
|
|
// MergeFrom(CodedInputStream) method to parse correctly.
|
|
var codedInput = new CodedInputStream(data);
|
|
var parsed = new ParseContextEnabledMessageB();
|
|
codedInput.ReadRawMessage(parsed);
|
|
Assert.IsTrue(codedInput.IsAtEnd);
|
|
|
|
Assert.AreEqual(12345, parsed.A.Bb.OptionalInt32);
|
|
Assert.AreEqual(6789, parsed.OptionalInt32);
|
|
}
|
|
|
|
[Test]
|
|
public void LegacyGeneratedCodeThrowsWithReadOnlySequence()
|
|
{
|
|
var message = new ParseContextEnabledMessageB
|
|
{
|
|
A = new LegacyGeneratedCodeMessageA
|
|
{
|
|
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
|
|
},
|
|
OptionalInt32 = 6789
|
|
};
|
|
var data = message.ToByteArray();
|
|
|
|
// if parsing started using ReadOnlySequence and we don't have a CodedInputStream
|
|
// instance at hand, we cannot fall back to the legacy MergeFrom(CodedInputStream)
|
|
// method and parsing will fail. As a consequence, one can only use parsing
|
|
// from ReadOnlySequence if all the messages in the parsing tree have their generated
|
|
// code up to date.
|
|
var exception = Assert.Throws<InvalidProtocolBufferException>(() =>
|
|
{
|
|
ParseContext.Initialize(new ReadOnlySequence<byte>(data), out ParseContext parseCtx);
|
|
var parsed = new ParseContextEnabledMessageB();
|
|
ParsingPrimitivesMessages.ReadRawMessage(ref parseCtx, parsed);
|
|
});
|
|
Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables ParseContext-based parsing. You might need to regenerate the generated protobuf code.", exception.Message);
|
|
}
|
|
|
|
[Test]
|
|
public void IntermixingOfNewAndLegacyGeneratedCodeWorksWithCodedOutputStream()
|
|
{
|
|
// when serialization started using CodedOutputStream and a message with legacy generated code
|
|
// is encountered somewhere in the parse tree, we still need to be able to use its
|
|
// WriteTo(CodedOutputStream) method to serialize correctly.
|
|
var ms = new MemoryStream();
|
|
var codedOutput = new CodedOutputStream(ms);
|
|
var message = new ParseContextEnabledMessageB
|
|
{
|
|
A = new LegacyGeneratedCodeMessageA
|
|
{
|
|
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
|
|
},
|
|
OptionalInt32 = 6789
|
|
};
|
|
message.WriteTo(codedOutput);
|
|
codedOutput.Flush();
|
|
|
|
var codedInput = new CodedInputStream(ms.ToArray());
|
|
var parsed = new ParseContextEnabledMessageB();
|
|
codedInput.ReadRawMessage(parsed);
|
|
Assert.IsTrue(codedInput.IsAtEnd);
|
|
|
|
Assert.AreEqual(12345, parsed.A.Bb.OptionalInt32);
|
|
Assert.AreEqual(6789, parsed.OptionalInt32);
|
|
}
|
|
|
|
[Test]
|
|
public void LegacyGeneratedCodeThrowsWithIBufferWriter()
|
|
{
|
|
// if serialization started using IBufferWriter and we don't have a CodedOutputStream
|
|
// instance at hand, we cannot fall back to the legacy WriteTo(CodedOutputStream)
|
|
// method and serializatin will fail. As a consequence, one can only use serialization
|
|
// to IBufferWriter if all the messages in the parsing tree have their generated
|
|
// code up to date.
|
|
var message = new ParseContextEnabledMessageB
|
|
{
|
|
A = new LegacyGeneratedCodeMessageA
|
|
{
|
|
Bb = new ParseContextEnabledMessageB { OptionalInt32 = 12345 }
|
|
},
|
|
OptionalInt32 = 6789
|
|
};
|
|
var exception = Assert.Throws<InvalidProtocolBufferException>(() =>
|
|
{
|
|
WriteContext.Initialize(new TestArrayBufferWriter<byte>(), out WriteContext writeCtx);
|
|
((IBufferMessage)message).InternalWriteTo(ref writeCtx);
|
|
});
|
|
Assert.AreEqual($"Message {typeof(LegacyGeneratedCodeMessageA).Name} doesn't provide the generated method that enables WriteContext-based serialization. You might need to regenerate the generated protobuf code.", exception.Message);
|
|
}
|
|
|
|
// hand-modified version of a generated message that only provides the legacy
|
|
// MergeFrom(CodedInputStream) method and doesn't implement IBufferMessage.
|
|
private sealed partial class LegacyGeneratedCodeMessageA : pb::IMessage {
|
|
private pb::UnknownFieldSet _unknownFields;
|
|
|
|
pbr::MessageDescriptor pb::IMessage.Descriptor => throw new System.NotImplementedException();
|
|
|
|
/// <summary>Field number for the "bb" field.</summary>
|
|
public const int BbFieldNumber = 1;
|
|
private ParseContextEnabledMessageB bb_;
|
|
public ParseContextEnabledMessageB Bb {
|
|
get { return bb_; }
|
|
set {
|
|
bb_ = value;
|
|
}
|
|
}
|
|
|
|
public void WriteTo(pb::CodedOutputStream output) {
|
|
if (bb_ != null) {
|
|
output.WriteRawTag(10);
|
|
output.WriteMessage(Bb);
|
|
}
|
|
if (_unknownFields != null) {
|
|
_unknownFields.WriteTo(output);
|
|
}
|
|
}
|
|
|
|
public int CalculateSize() {
|
|
int size = 0;
|
|
if (bb_ != null) {
|
|
size += 1 + pb::CodedOutputStream.ComputeMessageSize(Bb);
|
|
}
|
|
if (_unknownFields != null) {
|
|
size += _unknownFields.CalculateSize();
|
|
}
|
|
return size;
|
|
}
|
|
|
|
public void MergeFrom(pb::CodedInputStream input) {
|
|
uint tag;
|
|
while ((tag = input.ReadTag()) != 0) {
|
|
switch(tag) {
|
|
default:
|
|
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
|
|
break;
|
|
case 10: {
|
|
if (bb_ == null) {
|
|
Bb = new ParseContextEnabledMessageB();
|
|
}
|
|
input.ReadMessage(Bb);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// hand-modified version of a generated message that does provide
|
|
// the new InternalMergeFrom(ref ParseContext) method.
|
|
private sealed partial class ParseContextEnabledMessageB : pb::IBufferMessage {
|
|
private pb::UnknownFieldSet _unknownFields;
|
|
|
|
pbr::MessageDescriptor pb::IMessage.Descriptor => throw new System.NotImplementedException();
|
|
|
|
/// <summary>Field number for the "a" field.</summary>
|
|
public const int AFieldNumber = 1;
|
|
private LegacyGeneratedCodeMessageA a_;
|
|
public LegacyGeneratedCodeMessageA A {
|
|
get { return a_; }
|
|
set {
|
|
a_ = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>Field number for the "optional_int32" field.</summary>
|
|
public const int OptionalInt32FieldNumber = 2;
|
|
private int optionalInt32_;
|
|
public int OptionalInt32 {
|
|
get { return optionalInt32_; }
|
|
set {
|
|
optionalInt32_ = value;
|
|
}
|
|
}
|
|
|
|
public void WriteTo(pb::CodedOutputStream output) {
|
|
output.WriteRawMessage(this);
|
|
}
|
|
|
|
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output)
|
|
{
|
|
if (a_ != null)
|
|
{
|
|
output.WriteRawTag(10);
|
|
output.WriteMessage(A);
|
|
}
|
|
if (OptionalInt32 != 0)
|
|
{
|
|
output.WriteRawTag(16);
|
|
output.WriteInt32(OptionalInt32);
|
|
}
|
|
if (_unknownFields != null)
|
|
{
|
|
_unknownFields.WriteTo(ref output);
|
|
}
|
|
}
|
|
|
|
public int CalculateSize() {
|
|
int size = 0;
|
|
if (a_ != null) {
|
|
size += 1 + pb::CodedOutputStream.ComputeMessageSize(A);
|
|
}
|
|
if (OptionalInt32 != 0) {
|
|
size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32);
|
|
}
|
|
if (_unknownFields != null) {
|
|
size += _unknownFields.CalculateSize();
|
|
}
|
|
return size;
|
|
}
|
|
public void MergeFrom(pb::CodedInputStream input) {
|
|
input.ReadRawMessage(this);
|
|
}
|
|
|
|
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
|
|
uint tag;
|
|
while ((tag = input.ReadTag()) != 0) {
|
|
switch(tag) {
|
|
default:
|
|
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
|
|
break;
|
|
case 10: {
|
|
if (a_ == null) {
|
|
A = new LegacyGeneratedCodeMessageA();
|
|
}
|
|
input.ReadMessage(A);
|
|
break;
|
|
}
|
|
case 16: {
|
|
OptionalInt32 = input.ReadInt32();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |