Skip to content

Commit

Permalink
Add reserved fields to proto generator
Browse files Browse the repository at this point in the history
  • Loading branch information
ltrzesniewski committed Jan 15, 2024
1 parent fe2fe81 commit d348056
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 3 deletions.
4 changes: 2 additions & 2 deletions src/Abc.Zebus.MessageDsl.Tests/MessageDsl/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ static GeneratorTests()
protected abstract string SnapshotExtension { get; }
protected abstract string GenerateRaw(ParsedContracts contracts);

[MustUseReturnValue]
protected string Generate(MessageDefinition message)
{
var contracts = new ParsedContracts();
contracts.Messages.Add(message);
return Generate(contracts);
}

[MustUseReturnValue]
protected string Generate(ParsedContracts contracts)
{
PreProcess(contracts);
Expand All @@ -40,15 +42,13 @@ protected string Generate(ParsedContracts contracts)
return result;
}

[MustUseReturnValue]
protected Task<string> Verify(MessageDefinition message)
{
var contracts = new ParsedContracts();
contracts.Messages.Add(message);
return Verify(contracts);
}

[MustUseReturnValue]
protected async Task<string> Verify(ParsedContracts contracts)
{
PreProcess(contracts);
Expand Down
26 changes: 26 additions & 0 deletions src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ProtoGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using Abc.Zebus.MessageDsl.Analysis;
using Abc.Zebus.MessageDsl.Ast;
using Abc.Zebus.MessageDsl.Generator;
using Abc.Zebus.MessageDsl.Tests.TestTools;
Expand Down Expand Up @@ -190,6 +191,31 @@ public async Task should_handle_message_inheritance()
code.ShouldContain("optional MsgC _subTypeMsgC = 11;");
}

[Test]
public async Task should_generate_reservations()
{
await Verify(new MessageDefinition
{
Name = "MsgA",
Parameters =
{
new ParameterDefinition("int?", "foo"),
},
ReservedRanges =
{
new ReservationRange(2),
new ReservationRange(10, 15),
new ReservationRange(8, 14),
new ReservationRange(16),
new ReservationRange(42)
},
Options =
{
Proto = true
}
});
}

protected override string SnapshotExtension => "proto";

protected override string GenerateRaw(ParsedContracts contracts)
Expand Down
18 changes: 18 additions & 0 deletions src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ReservationRangeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Abc.Zebus.MessageDsl.Analysis;
using Abc.Zebus.MessageDsl.Tests.TestTools;
using NUnit.Framework;

namespace Abc.Zebus.MessageDsl.Tests.MessageDsl;

[TestFixture]
public class ReservationRangeTests
{
[Test]
public void should_compress_ranges()
{
ReservationRange.Compress([new(2, 4), new(3, 5), new(6, 7), new(10, 12)])
.ShouldEqual([new(2, 7), new(10, 12)]);

ReservationRange.Compress([]).ShouldEqual([]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

// Generated by Abc.Zebus.MessageDsl v1.2.3.4

import "servicebus.proto";

message MsgA {
option (servicebus.message).type = Event;

reserved 2, 8 to 16, 42;
optional int32 Foo = 1;
}
34 changes: 33 additions & 1 deletion src/Abc.Zebus.MessageDsl/Analysis/ReservationRange.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
using Abc.Zebus.MessageDsl.Ast;
using System;
using System.Collections.Generic;
using System.Linq;
using Abc.Zebus.MessageDsl.Ast;

namespace Abc.Zebus.MessageDsl.Analysis;

internal readonly struct ReservationRange(int startTag, int endTag)
{
public static ReservationRange None => default;

public int StartTag => startTag;
public int EndTag => endTag;

private bool IsValid => startTag > 0;

public ReservationRange(int tag)
Expand Down Expand Up @@ -37,6 +43,32 @@ public void AddToMessage(MessageDefinition message)
message.ReservedRanges.Add(this);
}

public static IEnumerable<ReservationRange> Compress(IEnumerable<ReservationRange> ranges)
{
var startTag = 0;
var endTag = 0;

foreach (var range in ranges.Where(i => i.IsValid).OrderBy(i => i.StartTag))
{
if (startTag == 0)
{
startTag = range.StartTag;
endTag = range.EndTag;
}

if (range.StartTag > endTag + 1)
{
yield return new ReservationRange(startTag, endTag);
startTag = range.StartTag;
}

endTag = Math.Max(endTag, range.EndTag);
}

if (startTag != 0)
yield return new ReservationRange(startTag, endTag);
}

public override string ToString()
=> IsValid
? startTag != endTag
Expand Down
25 changes: 25 additions & 0 deletions src/Abc.Zebus.MessageDsl/Generator/ProtoGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ private void WriteMessage(MessageDefinition message)
using (Block())
{
WriteMessageOptions(message);
WriteReservedFields(message);

foreach (var param in message.Parameters)
WriteField(param);
Expand All @@ -109,6 +110,30 @@ private void WriteMessageOptions(MessageDefinition message)
}
}

private void WriteReservedFields(MessageDefinition message)
{
if (message.ReservedRanges.Count == 0)
return;

Writer.Write("reserved ");
var first = true;

foreach (var reservation in ReservationRange.Compress(message.ReservedRanges))
{
if (first)
first = false;
else
Writer.Write(", ");

if (reservation.StartTag == reservation.EndTag)
Writer.Write(reservation.StartTag);
else
Writer.Write("{0} to {1}", reservation.StartTag, reservation.EndTag);
}

Writer.WriteLine(";");
}

private void WriteField(ParameterDefinition param)
{
Writer.Write(
Expand Down

0 comments on commit d348056

Please sign in to comment.