Skip to content

Commit

Permalink
Use VirtualTreeView only
Browse files Browse the repository at this point in the history
  • Loading branch information
martin-strecker-sonarsource committed Dec 27, 2023
1 parent 456b1ca commit 404f314
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 220 deletions.
36 changes: 18 additions & 18 deletions ProtoBuf.Logic/MessageBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ public void MergeFrom(CodedInputStream input)
: ParseUnknownField(input, new WireTag(index, type));
fields.AddRange(parsedFields);
}
Result = new TypedMessage(fields, messageDef);
Result = new TypedMessage(fields, messageDef, messageDef);
}

private IEnumerable<TypedField> ParseUnknownField(CodedInputStream stream, WireTag wireTag)
{
var (index, type) = wireTag;
var value = stream.ReadType(type);
yield return new TypedField("Unknown", index, new TypedUnknown(value));
yield return new TypedField("Unknown", index, null, new TypedUnknown(value));
}

private IEnumerable<TypedField> ParseField(CodedInputStream stream, ProtoContext protoContext, FieldType type, FieldContext field)
Expand All @@ -48,7 +48,7 @@ private IEnumerable<TypedField> ParseField(CodedInputStream stream, ProtoContext
var values = ReadExpectedType(stream, protoContext, type, field.type_());
foreach (var value in values)
{
yield return new TypedField(fieldName, index, value);
yield return new TypedField(fieldName, index, field, value);
}
}

Expand Down Expand Up @@ -78,38 +78,38 @@ private static IEnumerable<ProtoType> ReadExpectedType(CodedInputStream stream,
private static ProtoType? ReadExpectedType(CodedInputStream stream, ProtoContext protoContext, Type_Context expectedType)
{
if (expectedType.INT32() is not null)
return new TypedInt32(stream.ReadInt32());
return new TypedInt32(stream.ReadInt32(), expectedType);
else if (expectedType.INT64() is not null)
return new TypedInt64(stream.ReadInt64());
return new TypedInt64(stream.ReadInt64(), expectedType);
else if (expectedType.SINT32() is not null)
return new TypedSint32(stream.ReadSInt32());
return new TypedSint32(stream.ReadSInt32(), expectedType);
else if (expectedType.SINT64() is not null)
return new TypedSint64(stream.ReadSInt64());
return new TypedSint64(stream.ReadSInt64(), expectedType);
else if (expectedType.UINT32() is not null)
return new TypedUint32(stream.ReadUInt32());
return new TypedUint32(stream.ReadUInt32(), expectedType);
else if (expectedType.UINT64() is not null)
return new TypedUint64(stream.ReadUInt64());
return new TypedUint64(stream.ReadUInt64(), expectedType);
else if (expectedType.BOOL() is not null)
return new TypedBool(stream.ReadBool());
return new TypedBool(stream.ReadBool(), expectedType);
else if (expectedType.FIXED32() is not null)
return new TypedFixed32(stream.ReadFixed32());
return new TypedFixed32(stream.ReadFixed32(), expectedType);
else if (expectedType.FIXED64() is not null)
return new TypedFixed64(stream.ReadFixed64());
return new TypedFixed64(stream.ReadFixed64(), expectedType);
else if (expectedType.SFIXED32() is not null)
return new TypedSfixed32(stream.ReadSFixed32());
return new TypedSfixed32(stream.ReadSFixed32(), expectedType);
else if (expectedType.SFIXED64() is not null)
return new TypedSfixed64(stream.ReadSFixed64());
return new TypedSfixed64(stream.ReadSFixed64(), expectedType);
else if (expectedType.DOUBLE() is not null)
return new TypedDouble(stream.ReadDouble());
return new TypedDouble(stream.ReadDouble(), expectedType);
else if (expectedType.FLOAT() is not null)
return new TypedFloat(stream.ReadFloat());
return new TypedFloat(stream.ReadFloat(), expectedType);
else if (expectedType.STRING() is not null)
return new TypedString(stream.ReadString());
return new TypedString(stream.ReadString(), expectedType);
else if (expectedType.enumType() is not null || expectedType.messageType() is not null)
{
return BindMessageOrEnumDef(protoContext, expectedType) switch
{
EnumDefContext enumDef => new TypedEnum(stream.ReadEnum(), enumDef),
EnumDefContext enumDef => new TypedEnum(stream.ReadEnum(), expectedType, enumDef),
MessageDefContext innerMessageDef => ParseMessage(stream, protoContext, innerMessageDef),
_ => throw new NotImplementedException(),
};
Expand Down
10 changes: 1 addition & 9 deletions ProtoBuf.Logic/MessageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,7 @@ public record class MessageViewModel(Protobuf3Parser.MessageDefContext MessageDe
public HashSet<MessageViewModel> Nested { get => nested; }
public IReadOnlyCollection<FieldViewModel> Fields { get => fields; }

public string Definition => GetFullText(MessageDefContext);

public static string GetFullText(ParserRuleContext context)
{
if (context.Start == null || context.Stop == null || context.Start.StartIndex < 0 || context.Stop.StopIndex < 0)
return context.GetText(); // Fallback

return context.Start.InputStream.GetText(Interval.Of(context.Start.StartIndex, context.Stop.StopIndex));
}
public string Definition => MessageDefContext.GetFullText();

public class Visitor : Protobuf3BaseVisitor<bool>
{
Expand Down
27 changes: 27 additions & 0 deletions ProtoBuf.Logic/ParserRuleContextExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Antlr4.Runtime.Misc;
using Antlr4.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;

namespace ProtoBuf.Logic
{
public static class ParserRuleContextExtensions
{
[return: NotNullIfNotNull(nameof(context))]
public static string? GetFullText(this ParserRuleContext? context)
{
if (context==null)
{
return null;
}
if (context.Start == null || context.Stop == null || context.Start.StartIndex < 0 || context.Stop.StopIndex < 0)
return context.GetText(); // Fallback

return context.Start.InputStream.GetText(Interval.Of(context.Start.StartIndex, context.Stop.StopIndex));
}
}
}
46 changes: 25 additions & 21 deletions ProtoBuf.Logic/TypedMessageDecoder.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
using Antlr4.Runtime.Misc;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Google.Protobuf;
using static ProtoBuf.Antlr.Protobuf3Parser;

namespace ProtoBuf.Logic
{
public abstract record class ProtoType(string Type);
public sealed record class TypedDouble(double Value) : ProtoType("Double");
public sealed record class TypedFloat(float Value) : ProtoType("Float");
public sealed record class TypedInt32(Int32 Value) : ProtoType("Int32");
public sealed record class TypedInt64(Int64 Value) : ProtoType("Int64");
public sealed record class TypedUint32(UInt32 Value) : ProtoType("UInt32");
public sealed record class TypedUint64(UInt64 Value) : ProtoType("UInt64");
public sealed record class TypedSint32(Int32 Value) : ProtoType("SInt32");
public sealed record class TypedSint64(Int64 Value) : ProtoType("SInt64");
public sealed record class TypedFixed32(UInt32 Value) : ProtoType("Fixed32");
public sealed record class TypedFixed64(UInt64 Value) : ProtoType("Fixed64");
public sealed record class TypedSfixed32(Int32 Value) : ProtoType("Sfixed32");
public sealed record class TypedSfixed64(Int64 Value) : ProtoType("Sfixed64");
public sealed record class TypedBool(bool Value) : ProtoType("Bool");
public sealed record class TypedString(string Value) : ProtoType("String");
public sealed record class TypedBytes(ByteString Value) : ProtoType("Bytes");
public sealed record class TypedUnknown(object Value) : ProtoType("Unknown");
public sealed record class TypedMessage(IReadOnlyList<TypedField> Fields, MessageDefContext? MessageDef) : ProtoType("Message")
public abstract record class ProtoType(string Type, ParserRuleContext? TypeDefinition)
{
public string Definition => TypeDefinition?.GetFullText() ?? "No definition";
}
public sealed record class TypedDouble(double Value, ParserRuleContext? TypeDefinition) : ProtoType("Double", TypeDefinition);
public sealed record class TypedFloat(float Value, ParserRuleContext? TypeDefinition) : ProtoType("Float", TypeDefinition);
public sealed record class TypedInt32(Int32 Value, ParserRuleContext? TypeDefinition) : ProtoType("Int32", TypeDefinition);
public sealed record class TypedInt64(Int64 Value, ParserRuleContext? TypeDefinition) : ProtoType("Int64", TypeDefinition);
public sealed record class TypedUint32(UInt32 Value, ParserRuleContext? TypeDefinition) : ProtoType("UInt32", TypeDefinition);
public sealed record class TypedUint64(UInt64 Value, ParserRuleContext? TypeDefinition) : ProtoType("UInt64", TypeDefinition);
public sealed record class TypedSint32(Int32 Value, ParserRuleContext? TypeDefinition) : ProtoType("SInt32", TypeDefinition);
public sealed record class TypedSint64(Int64 Value, ParserRuleContext? TypeDefinition) : ProtoType("SInt64", TypeDefinition);
public sealed record class TypedFixed32(UInt32 Value, ParserRuleContext? TypeDefinition) : ProtoType("Fixed32", TypeDefinition);
public sealed record class TypedFixed64(UInt64 Value, ParserRuleContext? TypeDefinition) : ProtoType("Fixed64", TypeDefinition);
public sealed record class TypedSfixed32(Int32 Value, ParserRuleContext? TypeDefinition) : ProtoType("Sfixed32", TypeDefinition);
public sealed record class TypedSfixed64(Int64 Value, ParserRuleContext? TypeDefinition) : ProtoType("Sfixed64", TypeDefinition);
public sealed record class TypedBool(bool Value, ParserRuleContext? TypeDefinition) : ProtoType("Bool", TypeDefinition);
public sealed record class TypedString(string Value, ParserRuleContext? TypeDefinition) : ProtoType("String", TypeDefinition);
public sealed record class TypedBytes(ByteString Value, ParserRuleContext? TypeDefinition) : ProtoType("Bytes", TypeDefinition);
public sealed record class TypedUnknown(object Value) : ProtoType("Unknown", null);
public sealed record class TypedMessage(IReadOnlyList<TypedField> Fields, ParserRuleContext? TypeDefinition, MessageDefContext? MessageDef) : ProtoType("Message", TypeDefinition)
{
public string MessageType => MessageDef == null ? "Unknown message type" : MessageDef.messageName().GetText();

Expand All @@ -35,7 +39,7 @@ public static string GetFullText(MessageDefContext context)
return context.Start.InputStream.GetText(Interval.Of(context.Start.StartIndex, context.Stop.StopIndex));
}
}
public sealed record class TypedEnum(int Value, EnumDefContext? EnumDef) : ProtoType("Enum")
public sealed record class TypedEnum(int Value, ParserRuleContext? TypeDefinition, EnumDefContext? EnumDef) : ProtoType("Enum", TypeDefinition)
{
public string EnumType => EnumDef == null ? "Unknown enum type" : EnumDef.enumName().GetText();
public string EnumValue => EnumDef?.enumBody().enumElement().FirstOrDefault(
Expand All @@ -51,7 +55,7 @@ public static string GetFullText(EnumDefContext context)
}
}

public sealed record class TypedField(string Name, int Index, ProtoType Value): ProtoType(Value.Type);
public sealed record class TypedField(string Name, int Index, ParserRuleContext? TypeDefinition, ProtoType Value): ProtoType(Value.Type, TypeDefinition);

public class TypedMessageDecoder
{
Expand Down
47 changes: 47 additions & 0 deletions ProtoBufViewer.Blazor/Pages/Index.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using Google.Protobuf;
using Microsoft.AspNetCore.Components.Forms;
using ProtoBuf.Logic;
using static ProtoBuf.Antlr.Protobuf3Parser;

namespace ProtoBufViewer.Blazor.Pages
{
public partial class Index
{
private const string DefaultDragClass = "relative rounded-lg border-2 border-dashed pa-4 mt-4 mud-width-full mud-height-full z-10";
private IBrowserFile? ProtoFile;
private IBrowserFile? ProtoBinFile;
HashSet<MessageViewModel> Messages { get; } = new();
MessageViewModel? SelectedMessage { get; set; }
ProtoContext? ParseResult { get; set; }

List<ProtoType>? TypedMessages { get; set; }

private async Task MessageFileChanged(IBrowserFile file)
{
ProtoFile = file;
Messages.Clear();
using var ms = new MemoryStream();
await file.OpenReadStream().CopyToAsync(ms);
ms.Position = 0;
ParseResult = ProtoParser.ParseFile(ms);
var visitor = new MessageViewModel.Visitor();
visitor.Visit(ParseResult);
foreach (var m in visitor.Messages.Where(x => x.Parent == null))
{
Messages.Add(m);
}
}

private async Task BinFilesChanged(IBrowserFile file)
{
ProtoBinFile = file;
using var ms = new MemoryStream();
await file.OpenReadStream().CopyToAsync(ms);
ms.Position = 0;
using var coded = CodedInputStream.CreateWithLimits(ms, int.MaxValue, int.MaxValue);
var decoder = new TypedMessageDecoder();
var result = decoder.Parse(coded, ParseResult, SelectedMessage.MessageDefContext);
TypedMessages = new(result);
}
}
}
Loading

0 comments on commit 404f314

Please sign in to comment.