Skip to content

Commit

Permalink
Merge branch 'master' into test-fixt
Browse files Browse the repository at this point in the history
  • Loading branch information
Ygg01 authored Dec 31, 2023
2 parents 4ff788e + 229e0fe commit 6fbefb0
Showing 1 changed file with 65 additions and 57 deletions.
122 changes: 65 additions & 57 deletions Linguini.Bundle/FluentBundle.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
Expand All @@ -20,7 +21,8 @@ namespace Linguini.Bundle
public class FluentBundle
{
private IDictionary<string, FluentFunction> _funcList;
private IDictionary<(string, EntryKind), IEntry> _entries;
private IDictionary<string, AstTerm> _terms;
private IDictionary<string, AstMessage> _messages;

#region Properties
/// <summary>
Expand Down Expand Up @@ -66,7 +68,8 @@ public class FluentBundle

private FluentBundle()
{
_entries = new Dictionary<(string, EntryKind), IEntry>();
_terms = new Dictionary<string, AstTerm>();
_messages = new Dictionary<string, AstMessage>();
_funcList = new Dictionary<string, FluentFunction>();
Culture = CultureInfo.CurrentCulture;
Locales = new List<string>();
Expand Down Expand Up @@ -95,24 +98,28 @@ private static FluentBundle ConstructBundle(FluentBundleOption option)
: CultureInfo.CurrentCulture.Name;
var cultureInfo = new CultureInfo(primaryLocale, false);
var locales = new List<string> { primaryLocale };
IDictionary<(string, EntryKind), IEntry> entries;
IDictionary<string, AstTerm> terms;
IDictionary<string, AstMessage> messages;
IDictionary<string, FluentFunction> functions;
if (option.UseConcurrent)
{
entries = new ConcurrentDictionary<(string, EntryKind), IEntry>();
terms = new ConcurrentDictionary<string, AstTerm>();
messages = new ConcurrentDictionary<string, AstMessage>();
functions = new ConcurrentDictionary<string, FluentFunction>();
}
else
{
entries = new Dictionary<(string, EntryKind), IEntry>();
terms = new Dictionary<string, AstTerm>();
messages = new Dictionary<string, AstMessage>();
functions = new Dictionary<string, FluentFunction>();
}

return new FluentBundle
{
Culture = cultureInfo,
Locales = locales,
_entries = entries,
_terms = terms,
_messages = messages,
_funcList = functions,
TransformFunc = option.TransformFunc,
FormatterFunc = option.FormatterFunc,
Expand Down Expand Up @@ -153,10 +160,10 @@ internal bool AddResource(Resource res, out List<FluentError> errors)
switch (entry)
{
case AstMessage message:
AddEntry(errors, message);
AddMessage(errors, message);
break;
case AstTerm term:
AddEntry(errors, term);
AddTerm(errors, term);
break;
}
}
Expand All @@ -175,17 +182,26 @@ private void InternalResourceOverriding(Resource resource)
{
var entry = resource.Entries[entryPos];

if (entry is AstTerm or AstMessage)
switch (entry)
{
AddEntryOverriding(entry);
case AstMessage message:
AddMessageOverriding(message);
break;
case AstTerm term:
AddTermOverriding(term);
break;
}
}
}

private void AddEntryOverriding(IEntry term)

private void AddMessageOverriding(AstMessage message)
{
_messages[message.GetId()] = message;
}

private void AddTermOverriding(AstTerm term)
{
var id = (term.GetId(), term.ToKind());
_entries[id] = term;
_terms[term.GetId()] = term;
}

public void AddResourceOverriding(string input)
Expand All @@ -200,19 +216,36 @@ public void AddResourceOverriding(TextReader input)
InternalResourceOverriding(res);
}

private void AddEntry(List<FluentError> errors, IEntry term)
private void AddTerm(List<FluentError> errors, AstTerm term)
{
var id = (term.GetId(), term.ToKind());
if (_entries.ContainsKey(id))
var termId = term.GetId();
// ReSharper disable once CanSimplifyDictionaryLookupWithTryAdd
// Using TryAdd here leads to undocumented exceptions
if (_terms.ContainsKey(termId))
{
errors.Add(new OverrideFluentError(id.Item1, id.Item2));
errors.Add(new OverrideFluentError(termId, EntryKind.Term));
}
else
{
_entries[id] = term;
_terms[termId] = term;
}
}


private void AddMessage(List<FluentError> errors, AstMessage msg)
{
var msgId = msg.GetId();
// ReSharper disable once CanSimplifyDictionaryLookupWithTryAdd
// Using TryAdd here leads to undocumented exceptions
if (_messages.ContainsKey(msgId))
{
errors.Add(new OverrideFluentError(msg.GetId(), EntryKind.Message));
}
else
{
_messages[msgId] = msg;
}
}

public bool TryAddFunction(string funcName, ExternalFunction fluentFunction)
{
return TryInsert(funcName, fluentFunction, InsertBehavior.None);
Expand Down Expand Up @@ -276,9 +309,7 @@ private bool TryInsert(string funcName, ExternalFunction fluentFunction,
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool HasMessage(string identifier)
{
var id = (identifier, EntryKind.Message);
return _entries.ContainsKey(id)
&& _entries[id] is AstMessage;
return _messages.ContainsKey(identifier);
}

public bool HasAttrMessage(string idWithAttr)
Expand Down Expand Up @@ -374,34 +405,12 @@ public bool TryGetMessage(string id, string? attribute, FluentArgs? args,

public bool TryGetAstMessage(string ident, [NotNullWhen(true)] out AstMessage? message)
{
var id = (ident, EntryKind.Message);
if (_entries.ContainsKey(id)
&& _entries.TryGetValue(id, out var value)
&& value.ToKind() == EntryKind.Message
&& _entries[id] is AstMessage astMessage)
{
message = astMessage;
return true;
}

message = null;
return false;
return _messages.TryGetValue(ident, out message);
}

public bool TryGetAstTerm(string ident, [NotNullWhen(true)] out AstTerm? term)
{
var termId = (ident, EntryKind.Term);
if (_entries.ContainsKey(termId)
&& _entries.TryGetValue(termId, out var value)
&& value.ToKind() == EntryKind.Term
&& _entries[termId] is AstTerm astTerm)
{
term = astTerm;
return true;
}

term = null;
return false;
return _terms.TryGetValue(ident, out term);
}

public bool TryGetFunction(Identifier id, [NotNullWhen(true)] out FluentFunction? function)
Expand Down Expand Up @@ -433,19 +442,17 @@ public string FormatPattern(Pattern pattern, FluentArgs? args,

public IEnumerable<string> GetMessageEnumerable()
{
foreach (var keyValue in _entries)
{
if (keyValue.Value.ToKind() == EntryKind.Message)
yield return keyValue.Key.Item1;
}
return _messages.Keys;
}

public IEnumerable<string> GetFuncEnumerable()
{
foreach (var keyValue in _funcList)
{
yield return keyValue.Key;
}
return _funcList.Keys;
}

public IEnumerable<string> GetTermEnumerable()
{
return _terms.Keys;
}

public FluentBundle DeepClone()
Expand All @@ -455,7 +462,8 @@ public FluentBundle DeepClone()
Culture = (CultureInfo)Culture.Clone(),
FormatterFunc = FormatterFunc,
Locales = new List<string>(Locales),
_entries = new Dictionary<(string, EntryKind), IEntry>(_entries),
_messages = new Dictionary<string, AstMessage>(_messages),
_terms = new Dictionary<string, AstTerm>(_terms),
_funcList = new Dictionary<string, FluentFunction>(_funcList),
TransformFunc = TransformFunc,
UseIsolating = UseIsolating,
Expand Down

0 comments on commit 6fbefb0

Please sign in to comment.