-
Notifications
You must be signed in to change notification settings - Fork 12
feat: C# implementation based on the Java implementation #499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughAdds full C# implementation for the OpenFGA language: transformers (DSL↔JSON), mod file parser, validation utilities, error models, and supporting build/test tooling. Integrates C# into root Makefile and README. Introduces extensive C# tests and project scaffolding. Minor Java validation and transformer fixes. Updates test data cases. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant DSL as DSL String
participant Antlr as ANTLR Lexer/Parser
participant Listener as OpenFgaDslListener
participant Model as AuthorizationModel
participant Json as Json Helper
User->>DSL: Provide DSL
DSL->>Antlr: Tokenize/parse (error listener)
Antlr-->>Listener: Parse tree events
Listener-->>Model: Build model
Note over Antlr,Listener: On syntax errors, collect SyntaxError entries
alt Errors collected
Antlr-->>User: Throw DslErrorsException
else Success
Model->>Json: Serialize
Json-->>User: JSON string
end
sequenceDiagram
autonumber
actor User
participant JSON as JSON String
participant Parser as AuthorizationModel.FromJson
participant Tx as JsonToDslTransformer
participant DSL as DSL String
User->>JSON: Provide JSON
JSON->>Parser: Deserialize
Parser-->>Tx: AuthorizationModel
Tx-->>DSL: Format schema/types/relations/conditions
alt Invalid nesting
Tx-->>User: Throw UnsupportedDslNestingException
else Success
DSL-->>User: DSL string
end
sequenceDiagram
autonumber
actor User
participant Mod as .fga.mod Content
participant ModTx as FgaModTransformer
participant Out as FgaModFile
participant Json as Json Helper
User->>Mod: Provide mod file content
Mod->>ModTx: Parse YAML-like structure
ModTx->>ModTx: Validate schema/contents, collect errors
alt Errors exist
ModTx-->>User: Throw ModFileValidationError
else Success
ModTx-->>Out: Build FgaModFile
Out->>Json: Serialize
Json-->>User: JSON string
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
if (lines != null) { | ||
var rawLine = lines[lineIndex]; | ||
var regex = Pattern.compile("\\b" + symbol + "\\b"); | ||
var regex = Pattern.compile("\\b" + Pattern.quote(symbol) + "((?=\\W)|$)"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test in Java passed by chance before. Not because the expression was right.
The created regex pattern here was: \buser:*\b
going by the test was looking for user:*
in the line. The expression is actually matching only user
as :*
is matching nothing so that \b
can be a match. My understanding was that this was not the intention of the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 13
♻️ Duplicate comments (1)
pkg/csharp/src/OpenFga.Language/PartialRelationReference.cs (1)
13-13
: Null-forgiving operator usage is unsafe.Using the null-forgiving operator
!
on Line 13 suppresses compiler warnings but does not preventNullReferenceException
ifType
is actually null at runtime. This is flagged above in the comment for Line 6.
🧹 Nitpick comments (28)
pkg/csharp/src/OpenFga.Language/Validation/AllowableTypesResult.cs (1)
3-11
: Consider using IReadOnlyList for immutability.The
AllowableTypes
property exposes a mutableList<string>
, allowing callers to modify the internal state after construction. This breaks the immutability contract implied by the read-only property.Apply this diff to use
IReadOnlyList<string>
:internal class AllowableTypesResult { public bool Valid { get; } - public List<string> AllowableTypes { get; } + public IReadOnlyList<string> AllowableTypes { get; } public AllowableTypesResult(bool valid, List<string> allowableTypes) { Valid = valid; AllowableTypes = allowableTypes; } }This prevents external modifications while still allowing the list to be passed in from callers who construct it.
pkg/csharp/src/OpenFga.Language/Utils.cs (2)
4-10
: Add null guards for robustness.The method does not validate that
records
or any inner dictionary (kvp.Value
) is non-null. If a caller passesnull
forrecords
, or if any value in the dictionary isnull
, the method will throw aNullReferenceException
.Apply this diff to add null checks:
public static Dictionary<string, Dictionary<string, bool>> DeepCopy(Dictionary<string, Dictionary<string, bool>> records) { + if (records == null) { + throw new ArgumentNullException(nameof(records)); + } var copy = new Dictionary<string, Dictionary<string, bool>>(); foreach (var kvp in records) { + if (kvp.Value == null) { + throw new ArgumentException($"Inner dictionary for key '{kvp.Key}' cannot be null.", nameof(records)); + } copy[kvp.Key] = new Dictionary<string, bool>(kvp.Value); } return copy; }Alternatively, if
null
inner dictionaries should be preserved rather than rejected, you could use:public static Dictionary<string, Dictionary<string, bool>> DeepCopy(Dictionary<string, Dictionary<string, bool>> records) { + if (records == null) { + throw new ArgumentNullException(nameof(records)); + } var copy = new Dictionary<string, Dictionary<string, bool>>(); foreach (var kvp in records) { - copy[kvp.Key] = new Dictionary<string, bool>(kvp.Value); + copy[kvp.Key] = kvp.Value == null ? null : new Dictionary<string, bool>(kvp.Value); } return copy; }
3-11
: Add XML documentation comments.The utility class and method lack XML documentation. Adding summary tags will improve IDE IntelliSense and help consumers understand the method's purpose and behavior.
Apply this diff to add documentation:
+/// <summary> +/// Provides utility methods for common operations. +/// </summary> public static class Utils { + /// <summary> + /// Creates a deep copy of a nested dictionary structure. + /// </summary> + /// <param name="records">The dictionary to copy. Must not be null.</param> + /// <returns>A new dictionary with copied inner dictionaries.</returns> + /// <exception cref="ArgumentNullException">Thrown when <paramref name="records"/> is null.</exception> public static Dictionary<string, Dictionary<string, bool>> DeepCopy(Dictionary<string, Dictionary<string, bool>> records) {pkg/csharp/src/OpenFga.Language/PartialConditionParamTypeRef.cs (2)
5-8
: Consider making properties immutable with required initialization.The properties are currently mutable, but type references typically represent immutable structures. Without a constructor or required initialization,
TypeName
could remain in its default state, potentially causing issues downstream.Consider these improvements:
- Use
init
accessors or constructor-based initialization to ensureTypeName
is always set- Make properties read-only after construction to prevent unintended mutations
- Add validation if certain
TypeName
values or nullGenericTypes
elements are invalidExample refactor using
init
accessors with required modifier (C# 11+):public class PartialConditionParamTypeRef { - public TypeName TypeName { get; set; } - public List<ConditionParamTypeRef>? GenericTypes { get; set; } + public required TypeName TypeName { get; init; } + public List<ConditionParamTypeRef>? GenericTypes { get; init; }Alternatively, use a constructor:
public class PartialConditionParamTypeRef { public TypeName TypeName { get; } public List<ConditionParamTypeRef>? GenericTypes { get; } public PartialConditionParamTypeRef(TypeName typeName, List<ConditionParamTypeRef>? genericTypes = null) { TypeName = typeName; GenericTypes = genericTypes; } }
10-15
: Consider defensive copying of GenericTypes to prevent shared mutable state.The method directly assigns the
GenericTypes
list reference to the newConditionParamTypeRef
. If the list is later modified through the originalPartialConditionParamTypeRef
instance, it would affect the returned object, potentially leading to unexpected behavior.If immutability is desired, consider creating a defensive copy:
public ConditionParamTypeRef AsConditionParamTypeRef() { return new ConditionParamTypeRef() { TypeName = TypeName, - GenericTypes = GenericTypes + GenericTypes = GenericTypes != null ? new List<ConditionParamTypeRef>(GenericTypes) : null }; }Alternatively, if you adopt immutable properties as suggested earlier, this concern is mitigated.
pkg/csharp/OpenFga.Language.sln.DotSettings.user (1)
1-7
: Remove user-specific JetBrains settings file.This
.DotSettings.user
file holds local Rider cache paths and personal test sessions. It doesn’t belong in the shared repo and will churn across developers. Please drop it and add the pattern to.gitignore
.pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs (1)
1-2
: Remove unused using statement.Line 2 imports
System.Text.Json
but it's not used in this file. Remove it to keep the code clean.using SharpYaml.Serialization; -using System.Text.Json;
pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csproj (1)
12-14
: Update test package references to latest stable versions
- Microsoft.NET.Test.Sdk: 17.8.0 → 18.0.0
- xunit: 2.6.1 → 2.9.3
- xunit.runner.visualstudio: 2.5.3 → 3.1.5
pkg/csharp/test/OpenFga.Language.Tests/util/JsonValidationTestCase.cs (1)
15-16
: Inconsistent nullability annotation.
ExpectedErrors
is marked nullable (List<ModelValidationSingleError>?
) but initialized to a non-null empty list (new()
). Either remove the nullable marker if the property should never be null, or change the default tonull
if null is a valid state.Option 1 (recommended): Remove nullable marker
- public List<ModelValidationSingleError>? ExpectedErrors { get; set; } = new(); + public List<ModelValidationSingleError> ExpectedErrors { get; set; } = new();Option 2: Change default to null
- public List<ModelValidationSingleError>? ExpectedErrors { get; set; } = new(); + public List<ModelValidationSingleError>? ExpectedErrors { get; set; } = null;pkg/csharp/src/OpenFga.Language/Validation/ValidationOptions.cs (1)
3-16
: Consider using auto-properties with initializers.The current implementation uses explicit backing fields with simple getters and setters. Modern C# idiom favors auto-properties with initializers for cleaner, more concise code.
Apply this diff to simplify the implementation:
public class ValidationOptions { - private string _typePattern = $"^{Validator.Rules.Type}$"; - private string _relationPattern = $"^{Validator.Rules.Relation}$"; - - public string TypePattern { - get => _typePattern; - set => _typePattern = value; - } - - public string RelationPattern { - get => _relationPattern; - set => _relationPattern = value; - } + public string TypePattern { get; set; } = $"^{Validator.Rules.Type}$"; + public string RelationPattern { get; set; } = $"^{Validator.Rules.Relation}$"; }pkg/csharp/test/OpenFga.Language.Tests/FgaModToJsonShould.cs (3)
27-27
: Remove unused variable.The
different
variable is assigned but never used. This appears to be leftover debugging code.Apply this diff:
var expected = Json.Stringify(Json.Parse<FgaModFile>(json)); - var different = expected != generatedJson; Assert.Equal(expected, generatedJson);
40-40
: Remove unused variable.The
dif
variable is assigned but never used. This appears to be leftover debugging code.Apply this diff:
var expectedMessage = $"{errorsCount} error{(errorsCount > 1 ? "s" : "")} occurred:\n\t* {string.Join("\n\t* ", formattedErrors)}\n\n"; - var dif = expectedMessage != exception.Message; Assert.Equal(expectedMessage, exception.Message);
45-55
: Remove unnecessary null-forgiving operator.Line 51 uses the null-forgiving operator (
!
) ontestCase.Json
, which is nullable. Since the test method correctly handles null values (line 23), the null-forgiving operator suppresses a valid nullability warning without adding value.Apply this diff:
return TestsData.FgaModTransformTestCases .Select(testCase => new object[] { testCase.Name, testCase.ModFile, - testCase.Json!, + testCase.Json, testCase.Skip, testCase.ExpectedErrors });pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationError.cs (1)
8-16
: Consider using a more specific parameter type.The
MessagesFromErrors
method usesIEnumerable<object>
as the parameter type, but it only receivesList<ModFileValidationSingleError>
from the constructor. UsingIEnumerable<ModFileValidationSingleError>
would provide better type safety and make the intent clearer.Apply this diff:
- private static string MessagesFromErrors(IEnumerable<object> errors) { + private static string MessagesFromErrors(IEnumerable<ModFileValidationSingleError> errors) { var delimiter = "\n\t* "; var errorsCount = errors.Count(); var errorsPlural = errorsCount > 1 ? "s" : "";pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (1)
3-6
: Consider adding serialization attributes for consistency.Other error-related classes in the codebase (StartEnd, ValidationMetadata, ParsingError) include
[JsonPropertyName]
and[YamlMember]
attributes on their properties. If ErrorProperties instances are serialized to JSON or YAML anywhere in the error reporting pipeline, add these attributes for consistency.+using SharpYaml.Serialization; +using System.Text.Json.Serialization; + namespace OpenFga.Language.Errors; public class ErrorProperties { + [JsonPropertyName("line")] + [YamlMember("line")] public StartEnd? Line { get; set; } + [JsonPropertyName("column")] + [YamlMember("column")] public StartEnd? Column { get; set; } + [JsonPropertyName("message")] + [YamlMember("message")] public string Message { get; set; } = string.Empty;pkg/csharp/test/OpenFga.Language.Tests/util/FgaModTestCase.cs (1)
1-3
: Remove unused import.The
System.Text.Json.Serialization
namespace is imported but no[JsonPropertyName]
attributes are used in this file. Only YAML serialization attributes are present.using OpenFga.Language.Errors; using SharpYaml.Serialization; -using System.Text.Json.Serialization;
pkg/csharp/test/OpenFga.Language.Tests/util/InvalidDslSyntaxTestCase.cs (1)
1-3
: Remove unused import.The
System.Text.Json.Serialization
namespace is imported but no[JsonPropertyName]
attributes are used. Only YAML attributes are present.using SharpYaml.Serialization; -using System.Text.Json.Serialization;
pkg/csharp/test/OpenFga.Language.Tests/util/JsonSyntaxTestCase.cs (1)
1-3
: Remove unused import.The
System.Text.Json.Serialization
namespace is imported but no[JsonPropertyName]
attributes are used. Only YAML attributes are present.using SharpYaml.Serialization; -using System.Text.Json.Serialization;
pkg/csharp/src/OpenFga.Language/Json.cs (1)
14-19
: Clarify handling of JSON literal "null" andT
constructor requirement
Parse<T>
treats the four-character literal"null"
like empty ornull
, returningnew T()
. Consider returningnull
instead or documenting this behavior to avoid surprises.- Verified
FgaModFile
andAuthorizationModel
have implicit public parameterless constructors, soActivator.CreateInstance<T>()
succeeds. Document thatT
must expose a public parameterless constructor.pkg/csharp/src/OpenFga.Language/Validation/Validator.cs (3)
16-21
: Mislabelled regex names degrade error messagesObjectId/TypeId are built with name "object"; Type is built with name "condition". Use precise names for clearer diagnostics.
- public static readonly ValidationRegex ObjectId = - ValidationRegex.Build("object", $"^{Rules.Id}$"); + public static readonly ValidationRegex ObjectId = + ValidationRegex.Build("objectId", $"^{Rules.Id}$"); - public static readonly ValidationRegex TypeId = - ValidationRegex.Build("object", $"^{Rules.Type}:{Rules.Id}$"); + public static readonly ValidationRegex TypeId = + ValidationRegex.Build("typeId", $"^{Rules.Type}:{Rules.Id}$"); - public static readonly ValidationRegex Type = - ValidationRegex.Build("condition", $"^{Rules.Type}$"); + public static readonly ValidationRegex Type = + ValidationRegex.Build("type", $"^{Rules.Type}$");Also applies to: 37-39
3-10
: Make Validator staticAll members are static; declare the class static.
-public class Validator { +public static class Validator {
41-43
: ValidateObject may be over-restrictiveRequiring both TypeId and Object doubles constraints (length 2..256 + full type:id). If spec only requires type:id, simplify; otherwise confirm the length rule.
- public static bool ValidateObject(string objectValue) { - return Regexes.TypeId.Matches(objectValue) && Regexes.Object.Matches(objectValue); - } + public static bool ValidateObject(string objectValue) { + return Regexes.TypeId.Matches(objectValue); + }pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (2)
32-45
: Deterministic test discoveryDirectoryInfo.GetDirectories() order is OS-dependent. Sort to ensure stable test ordering.
- foreach (var directory in transformerCasesFolder.GetDirectories()) { + foreach (var directory in transformerCasesFolder + .EnumerateDirectories() + .OrderBy(d => d.Name, StringComparer.Ordinal)) {
82-89
: Prefer AppContext.BaseDirectory over GetExecutingAssembly().LocationSimpler and more robust (single-file and shadow-copy safe).
- var testAssemblyLocation = System.Reflection.Assembly.GetExecutingAssembly().Location; - var testDirectory = Path.GetDirectoryName(testAssemblyLocation); + var testDirectory = AppContext.BaseDirectory; var languageRoot = Path.GetFullPath(Path.Combine(testDirectory!, "../../../../..")); var fullPath = Path.Combine(languageRoot, relativePath); return fullPath;pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (1)
192-194
: Make ParseTypeName resilient to enum namingHardcoding "TYPENAME" prefix may not match SDK enum names. Try direct parse, then fallback, else throw.
- private TypeName ParseTypeName(string typeName) { - return Enum.Parse<TypeName>("TYPENAME" + typeName.ToUpper(), true); - } + private TypeName ParseTypeName(string typeName) { + if (Enum.TryParse<TypeName>(typeName, true, out var parsed)) { + return parsed; + } + if (Enum.TryParse<TypeName>("TYPENAME" + typeName.ToUpperInvariant(), true, out parsed)) { + return parsed; + } + throw new ArgumentException($"Unknown condition parameter type: {typeName}"); + }pkg/csharp/src/OpenFga.Language/Validation/Dsl.cs (1)
45-47
: Anchor the type line regex and escape typeNameAvoid partial matches within other statements; escape user-provided names.
- return FindLine(line => System.Text.RegularExpressions.Regex.IsMatch(line.Trim(), @$"type {typeName}(\s|$)"), skipIndex); + return FindLine( + line => System.Text.RegularExpressions.Regex.IsMatch( + line.Trim(), + @$"^type {System.Text.RegularExpressions.Regex.Escape(typeName)}(\s|$)"), + skipIndex);pkg/csharp/src/OpenFga.Language/Validation/ModelValidator.cs (2)
514-518
: Null-safe file keyingSourceInfo.File is null-forgiven; add a guard to avoid NREs.
- if (!_fileToModules.ContainsKey(sourceInfo.File!)) { - _fileToModules[sourceInfo.File!] = new HashSet<string>(); - } - _fileToModules[sourceInfo.File!].Add(module); + var file = sourceInfo.File; + if (string.IsNullOrWhiteSpace(file)) return; + if (!_fileToModules.ContainsKey(file)) { + _fileToModules[file] = new HashSet<string>(); + } + _fileToModules[file].Add(module);
77-116
: Avoid relying on C# 12 collection expressions in library codePatterns like
?? []
andforeach (... ?? [])
require C# 12 collection expressions. If your project targets earlier language versions, replace with Enumerable.Empty().Example:
-foreach (var typeDef in _authorizationModel.TypeDefinitions ?? []) { +foreach (var typeDef in _authorizationModel.TypeDefinitions ?? Enumerable.Empty<TypeDefinition>()) {Also applies to: 127-151, 152-170, 176-199, 202-217, 239-261, 275-286
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pkg/csharp/assets/FGAIcon.png
is excluded by!**/*.png
📒 Files selected for processing (70)
Makefile
(1 hunks)README.md
(1 hunks)pkg/csharp/.editorconfig
(1 hunks)pkg/csharp/.gitignore
(1 hunks)pkg/csharp/Makefile
(1 hunks)pkg/csharp/OpenFga.Language.sln.DotSettings.user
(1 hunks)pkg/csharp/OpenFga.Language.slnx
(1 hunks)pkg/csharp/README.md
(1 hunks)pkg/csharp/src/OpenFga.Language/DslToJsonTransformer.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ErrorType.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/Metadata.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationError.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationSingleError.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ModelValidationSingleError.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/SimpleError.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/SyntaxError.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/UnsupportedDSLNestingException.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ValidationError.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Errors/ValidationMetadata.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/FgaModFile.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Json.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/JsonToDslTransformer.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/ModFileArrayProperty.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/ModFileStringProperty.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/OpenFga.Language.csproj
(1 hunks)pkg/csharp/src/OpenFga.Language/OpenFgaDslErrorListener.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/PartialConditionParamTypeRef.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/PartialRelationReference.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Relation.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/StackRelation.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Utils.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Utils/ModelUtils.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/AllowableTypesResult.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/DestructuredTupleToUserset.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/Dsl.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/EntryPointOrLoop.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/InvalidChildRelationMetadata.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/Keyword.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/ModelValidator.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/RelationTargetParserResult.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/RewriteType.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/ValidationErrorsBuilder.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/ValidationOptions.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/ValidationRegex.cs
(1 hunks)pkg/csharp/src/OpenFga.Language/Validation/Validator.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/DslToJsonShould.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/FgaModToJsonShould.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/JsonToDslShould.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/ModelValidatorShould.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csproj
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/DslSyntaxTestCase.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/FgaModTestCase.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/InvalidDslSyntaxTestCase.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/JsonSyntaxTestCase.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/JsonValidationTestCase.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/ModelUtilsTest.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/MultipleInvalidDslSyntaxTestCase.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/ValidTransformerTestCase.cs
(1 hunks)pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs
(1 hunks)pkg/java/src/main/java/dev/openfga/language/JsonToDslTransformer.java
(1 hunks)pkg/java/src/main/java/dev/openfga/language/validation/ValidationErrorsBuilder.java
(1 hunks)tests/data/json-validation-cases.yaml
(1 hunks)tests/data/transformer/11-multiple-conditions/authorization-model.json
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (47)
pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationSingleError.cs (3)
pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (3)
ParsingError
(6-44)ParsingError
(19-19)ParsingError
(21-25)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (3)
ErrorProperties
(3-24)ErrorProperties
(8-8)ErrorProperties
(10-14)pkg/csharp/src/OpenFga.Language/Validation/ValidationErrorsBuilder.cs (2)
ErrorProperties
(9-11)ErrorProperties
(13-34)
pkg/csharp/src/OpenFga.Language/Validation/ValidationOptions.cs (1)
pkg/csharp/src/OpenFga.Language/Validation/Validator.cs (2)
Validator
(3-76)Rules
(4-10)
pkg/csharp/src/OpenFga.Language/ModFileStringProperty.cs (4)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (2)
StartEnd
(27-32)StartEnd
(34-39)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (4)
StartEnd
(6-37)StartEnd
(16-16)StartEnd
(18-21)StartEnd
(23-25)pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (2)
StartEnd
(165-168)StartEnd
(170-181)
pkg/csharp/src/OpenFga.Language/Errors/ErrorType.cs (1)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)
pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationError.cs (5)
pkg/java/src/main/java/dev/openfga/language/errors/Errors.java (1)
Errors
(8-28)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationSingleError.cs (3)
ModFileValidationSingleError
(3-9)ModFileValidationSingleError
(5-5)ModFileValidationSingleError
(7-8)pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs (1)
MessagesFromErrors
(8-16)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (1)
ToString
(41-43)pkg/csharp/src/OpenFga.Language/Errors/SimpleError.cs (1)
ToString
(17-19)
pkg/csharp/src/OpenFga.Language/Validation/ModelValidator.cs (10)
pkg/csharp/src/OpenFga.Language/Validation/ValidationOptions.cs (1)
ValidationOptions
(3-16)pkg/csharp/src/OpenFga.Language/Validation/Dsl.cs (12)
Dsl
(5-106)Dsl
(8-10)GetSchemaLineNumber
(37-39)GetTypeLineNumber
(41-43)GetTypeLineNumber
(45-47)GetRelationLineNumber
(33-35)GetConditionLineNumber
(25-27)GetConditionLineNumber
(29-31)GetRelationDefName
(49-59)GetTypeRestrictionString
(91-105)List
(87-89)RelationTargetParserResult
(61-85)pkg/csharp/src/OpenFga.Language/Validation/ValidationErrorsBuilder.cs (26)
ValidationErrorsBuilder
(6-220)RaiseSchemaVersionRequired
(36-40)RaiseInvalidSchemaVersion
(42-46)RaiseMultipleModulesInSingleFile
(205-211)ThrowIfNotEmpty
(215-219)RaiseReservedTypeName
(48-53)RaiseInvalidName
(55-57)RaiseInvalidName
(59-65)RaiseReservedRelationName
(67-72)RaiseDuplicateRelationName
(74-76)RaiseDuplicateTypeName
(149-154)RaiseNoEntryPointLoop
(177-182)RaiseNoEntryPoint
(184-189)RaiseDifferentNestedConditionName
(198-203)RaiseUnusedCondition
(191-196)RaiseThisNotInFirstPlace
(170-175)RaiseDuplicateType
(163-168)RaiseDuplicateTypeRestriction
(156-161)RaiseAssignableRelationMustHaveTypes
(88-97)RaiseInvalidType
(99-108)RaiseInvalidConditionNameInParameter
(110-115)RaiseAssignableTypeWildcardRelation
(117-122)RaiseInvalidTypeRelation
(124-129)RaiseInvalidRelationError
(78-86)RaiseTupleUsersetRequiresDirect
(138-147)RaiseInvalidRelationOnTupleset
(131-136)pkg/csharp/src/OpenFga.Language/Validation/ValidationRegex.cs (4)
ValidationRegex
(5-32)ValidationRegex
(9-12)ValidationRegex
(17-27)Matches
(29-31)pkg/csharp/src/OpenFga.Language/Utils.cs (1)
Dictionary
(4-10)pkg/csharp/src/OpenFga.Language/Validation/EntryPointOrLoop.cs (4)
EntryPointOrLoop
(5-155)EntryPointOrLoop
(15-151)HasEntry
(153-153)IsLoop
(154-154)pkg/csharp/src/OpenFga.Language/Validation/RelationTargetParserResult.cs (2)
RelationTargetParserResult
(3-13)RelationTargetParserResult
(8-12)pkg/csharp/src/OpenFga.Language/Validation/DestructuredTupleToUserset.cs (3)
DestructuredTupleToUserset
(3-28)DestructuredTupleToUserset
(9-14)DestructuredTupleToUserset
(16-27)pkg/csharp/src/OpenFga.Language/Validation/InvalidChildRelationMetadata.cs (2)
InvalidChildRelationMetadata
(3-17)InvalidChildRelationMetadata
(10-16)pkg/csharp/src/OpenFga.Language/Validation/AllowableTypesResult.cs (2)
AllowableTypesResult
(3-11)AllowableTypesResult
(7-10)
pkg/csharp/src/OpenFga.Language/Validation/AllowableTypesResult.cs (2)
pkg/csharp/src/OpenFga.Language/Validation/ModelValidator.cs (1)
AllowableTypesResult
(449-465)pkg/csharp/src/OpenFga.Language/Validation/Dsl.cs (1)
List
(87-89)
pkg/csharp/src/OpenFga.Language/FgaModFile.cs (3)
pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (2)
FgaModFile
(17-19)FgaModFile
(21-63)pkg/csharp/src/OpenFga.Language/ModFileStringProperty.cs (1)
ModFileStringProperty
(6-15)pkg/csharp/src/OpenFga.Language/ModFileArrayProperty.cs (1)
ModFileArrayProperty
(6-15)
pkg/csharp/test/OpenFga.Language.Tests/util/JsonValidationTestCase.cs (3)
pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (6)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs (1)
List
(7-11)pkg/csharp/src/OpenFga.Language/Errors/ModelValidationSingleError.cs (3)
ModelValidationSingleError
(6-17)ModelValidationSingleError
(11-11)ModelValidationSingleError
(13-16)
pkg/csharp/src/OpenFga.Language/JsonToDslTransformer.cs (1)
pkg/java/src/main/java/dev/openfga/language/JsonToDslTransformer.java (2)
JsonToDslTransformer
(13-393)DirectAssignmentValidator
(180-220)
pkg/csharp/test/OpenFga.Language.Tests/FgaModToJsonShould.cs (6)
pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (7)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)TestsData
(5-90)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationSingleError.cs (3)
ModFileValidationSingleError
(3-9)ModFileValidationSingleError
(5-5)ModFileValidationSingleError
(7-8)pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (4)
FgaModTransformer
(10-186)Transform
(13-15)FgaModFile
(17-19)FgaModFile
(21-63)pkg/csharp/src/OpenFga.Language/Json.cs (2)
Json
(6-24)Stringify
(21-23)pkg/csharp/src/OpenFga.Language/FgaModFile.cs (1)
FgaModFile
(5-11)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationError.cs (1)
ModFileValidationError
(3-17)
pkg/csharp/test/OpenFga.Language.Tests/JsonToDslShould.cs (2)
pkg/csharp/src/OpenFga.Language/JsonToDslTransformer.cs (2)
JsonToDslTransformer
(7-328)Transform
(10-17)pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (1)
TestsData
(5-90)
pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (5)
pkg/csharp/src/OpenFga.Language/Errors/SimpleError.cs (4)
SimpleError
(6-20)SimpleError
(11-11)SimpleError
(13-15)ToString
(17-19)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (4)
StartEnd
(6-37)StartEnd
(16-16)StartEnd
(18-21)StartEnd
(23-25)pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (2)
StartEnd
(165-168)StartEnd
(170-181)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (4)
ErrorProperties
(3-24)ErrorProperties
(8-8)ErrorProperties
(10-14)GetFullMessage
(16-23)pkg/csharp/src/OpenFga.Language/Validation/ValidationErrorsBuilder.cs (2)
ErrorProperties
(9-11)ErrorProperties
(13-34)
pkg/csharp/test/OpenFga.Language.Tests/util/ValidTransformerTestCase.cs (1)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)
pkg/csharp/src/OpenFga.Language/Errors/ValidationMetadata.cs (1)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)
pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (4)
pkg/csharp/src/OpenFga.Language/Validation/ValidationErrorsBuilder.cs (2)
ErrorProperties
(9-11)ErrorProperties
(13-34)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (2)
StartEnd
(27-32)StartEnd
(34-39)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (4)
StartEnd
(6-37)StartEnd
(16-16)StartEnd
(18-21)StartEnd
(23-25)pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (2)
StartEnd
(165-168)StartEnd
(170-181)
pkg/csharp/src/OpenFga.Language/Errors/ModelValidationSingleError.cs (3)
pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (3)
ParsingError
(6-44)ParsingError
(19-19)ParsingError
(21-25)pkg/csharp/src/OpenFga.Language/Errors/ValidationMetadata.cs (4)
ValidationMetadata
(6-41)ValidationMetadata
(27-27)ValidationMetadata
(29-32)ValidationMetadata
(34-40)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (3)
ErrorProperties
(3-24)ErrorProperties
(8-8)ErrorProperties
(10-14)
pkg/csharp/test/OpenFga.Language.Tests/util/DslSyntaxTestCase.cs (3)
pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (6)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs (1)
List
(7-11)pkg/csharp/src/OpenFga.Language/Errors/ModelValidationSingleError.cs (3)
ModelValidationSingleError
(6-17)ModelValidationSingleError
(11-11)ModelValidationSingleError
(13-16)
pkg/csharp/src/OpenFga.Language/Validation/RelationTargetParserResult.cs (1)
pkg/csharp/src/OpenFga.Language/Validation/Dsl.cs (1)
RelationTargetParserResult
(61-85)
pkg/csharp/src/OpenFga.Language/Errors/SyntaxError.cs (4)
pkg/csharp/src/OpenFga.Language/OpenFgaDslErrorListener.cs (2)
SyntaxError
(11-19)SyntaxError
(21-39)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (3)
ParsingError
(6-44)ParsingError
(19-19)ParsingError
(21-25)pkg/csharp/src/OpenFga.Language/Errors/Metadata.cs (3)
Metadata
(3-11)Metadata
(6-6)Metadata
(8-10)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (3)
ErrorProperties
(3-24)ErrorProperties
(8-8)ErrorProperties
(10-14)
pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (8)
pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationSingleError.cs (3)
ModFileValidationSingleError
(3-9)ModFileValidationSingleError
(5-5)ModFileValidationSingleError
(7-8)pkg/csharp/src/OpenFga.Language/Json.cs (2)
Json
(6-24)Stringify
(21-23)pkg/csharp/src/OpenFga.Language/FgaModFile.cs (1)
FgaModFile
(5-11)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (4)
StartEnd
(6-37)StartEnd
(16-16)StartEnd
(18-21)StartEnd
(23-25)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationError.cs (1)
ModFileValidationError
(3-17)pkg/csharp/src/OpenFga.Language/ModFileStringProperty.cs (1)
ModFileStringProperty
(6-15)pkg/csharp/src/OpenFga.Language/ModFileArrayProperty.cs (1)
ModFileArrayProperty
(6-15)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (3)
ErrorProperties
(3-24)ErrorProperties
(8-8)ErrorProperties
(10-14)
pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (7)
pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs (2)
List
(7-11)YamlHelper
(6-12)pkg/csharp/test/OpenFga.Language.Tests/util/ValidTransformerTestCase.cs (3)
ValidTransformerTestCase
(5-30)ValidTransformerTestCase
(18-18)ValidTransformerTestCase
(20-25)pkg/csharp/test/OpenFga.Language.Tests/util/DslSyntaxTestCase.cs (1)
DslSyntaxTestCase
(8-23)pkg/csharp/test/OpenFga.Language.Tests/util/MultipleInvalidDslSyntaxTestCase.cs (1)
MultipleInvalidDslSyntaxTestCase
(8-11)pkg/csharp/test/OpenFga.Language.Tests/util/JsonSyntaxTestCase.cs (1)
JsonSyntaxTestCase
(6-21)pkg/csharp/test/OpenFga.Language.Tests/util/FgaModTestCase.cs (1)
FgaModTestCase
(7-22)pkg/csharp/test/OpenFga.Language.Tests/util/JsonValidationTestCase.cs (1)
JsonValidationTestCase
(8-17)
pkg/csharp/src/OpenFga.Language/Validation/Dsl.cs (2)
pkg/csharp/src/OpenFga.Language/Validation/RelationTargetParserResult.cs (2)
RelationTargetParserResult
(3-13)RelationTargetParserResult
(8-12)pkg/csharp/src/OpenFga.Language/PartialRelationReference.cs (1)
RelationReference
(11-18)
pkg/csharp/src/OpenFga.Language/OpenFgaDslErrorListener.cs (5)
pkg/csharp/src/OpenFga.Language/Errors/SyntaxError.cs (3)
SyntaxError
(5-16)SyntaxError
(9-9)SyntaxError
(11-15)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (3)
ErrorProperties
(3-24)ErrorProperties
(8-8)ErrorProperties
(10-14)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (2)
StartEnd
(27-32)StartEnd
(34-39)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (4)
StartEnd
(6-37)StartEnd
(16-16)StartEnd
(18-21)StartEnd
(23-25)pkg/csharp/src/OpenFga.Language/Errors/Metadata.cs (3)
Metadata
(3-11)Metadata
(6-6)Metadata
(8-10)
pkg/csharp/test/OpenFga.Language.Tests/DslToJsonShould.cs (5)
pkg/csharp/src/OpenFga.Language/DslToJsonTransformer.cs (3)
DslToJsonTransformer
(9-69)Transform
(13-15)AuthorizationModel
(17-24)pkg/csharp/src/OpenFga.Language/Json.cs (2)
Json
(6-24)Stringify
(21-23)pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (1)
AuthorizationModel
(25-27)pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (7)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)TestsData
(5-90)pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs (1)
DslErrorsException
(3-17)
pkg/csharp/test/OpenFga.Language.Tests/util/JsonSyntaxTestCase.cs (1)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)
pkg/csharp/test/OpenFga.Language.Tests/util/ModelUtilsTest.cs (1)
pkg/csharp/src/OpenFga.Language/Utils/ModelUtils.cs (3)
ModelUtils
(5-71)GetModuleForObjectTypeRelation
(13-31)IsRelationAssignable
(39-70)
pkg/csharp/src/OpenFga.Language/PartialConditionParamTypeRef.cs (1)
pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (1)
TypeName
(192-194)
pkg/csharp/src/OpenFga.Language/Validation/EntryPointOrLoop.cs (3)
pkg/csharp/src/OpenFga.Language/Utils.cs (2)
Dictionary
(4-10)Utils
(3-11)pkg/csharp/src/OpenFga.Language/Validation/Dsl.cs (2)
Dsl
(5-106)Dsl
(8-10)pkg/csharp/src/OpenFga.Language/Validation/DestructuredTupleToUserset.cs (3)
DestructuredTupleToUserset
(3-28)DestructuredTupleToUserset
(9-14)DestructuredTupleToUserset
(16-27)
pkg/csharp/src/OpenFga.Language/StackRelation.cs (2)
pkg/csharp/src/OpenFga.Language/JsonToDslTransformer.cs (1)
List
(121-132)pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (1)
Userset
(29-65)
pkg/csharp/src/OpenFga.Language/Utils/ModelUtils.cs (3)
pkg/csharp/test/OpenFga.Language.Tests/util/ModelUtilsTest.cs (2)
TypeDefinition
(8-29)TypeDefinition
(31-39)pkg/csharp/src/OpenFga.Language/Errors/Metadata.cs (3)
Metadata
(3-11)Metadata
(6-6)Metadata
(8-10)pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (1)
Userset
(29-65)
pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (3)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (2)
StartEnd
(27-32)StartEnd
(34-39)pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (2)
StartEnd
(165-168)StartEnd
(170-181)
pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs (3)
pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (4)
ParsingError
(6-44)ParsingError
(19-19)ParsingError
(21-25)ToString
(41-43)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationError.cs (1)
MessagesFromErrors
(8-16)pkg/csharp/src/OpenFga.Language/Errors/SimpleError.cs (1)
ToString
(17-19)
pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (5)
pkg/csharp/src/OpenFga.Language/Relation.cs (1)
Relation
(9-14)pkg/csharp/src/OpenFga.Language/StackRelation.cs (1)
StackRelation
(8-11)pkg/csharp/src/OpenFga.Language/Errors/Metadata.cs (3)
Metadata
(3-11)Metadata
(6-6)Metadata
(8-10)pkg/csharp/src/OpenFga.Language/PartialConditionParamTypeRef.cs (2)
ConditionParamTypeRef
(10-15)PartialConditionParamTypeRef
(5-16)pkg/csharp/src/OpenFga.Language/PartialRelationReference.cs (2)
RelationReference
(11-18)PartialRelationReference
(5-19)
pkg/csharp/test/OpenFga.Language.Tests/util/MultipleInvalidDslSyntaxTestCase.cs (4)
pkg/csharp/test/OpenFga.Language.Tests/util/InvalidDslSyntaxTestCase.cs (1)
InvalidDslSyntaxTestCase
(6-18)pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (6)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs (1)
List
(7-11)pkg/csharp/src/OpenFga.Language/Errors/ModelValidationSingleError.cs (3)
ModelValidationSingleError
(6-17)ModelValidationSingleError
(11-11)ModelValidationSingleError
(13-16)
pkg/csharp/src/OpenFga.Language/Relation.cs (2)
pkg/csharp/src/OpenFga.Language/JsonToDslTransformer.cs (1)
List
(121-132)pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (1)
Userset
(29-65)
pkg/csharp/src/OpenFga.Language/Validation/ValidationRegex.cs (1)
pkg/go/validation/validation-rules.go (1)
Rule
(8-8)
pkg/csharp/src/OpenFga.Language/Errors/SimpleError.cs (2)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (1)
ToString
(41-43)
pkg/csharp/src/OpenFga.Language/Validation/RewriteType.cs (1)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)
pkg/csharp/src/OpenFga.Language/DslToJsonTransformer.cs (5)
pkg/csharp/src/OpenFga.Language/Json.cs (2)
Json
(6-24)Stringify
(21-23)pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs (2)
AuthorizationModel
(25-27)OpenFgaDslListener
(9-428)pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs (1)
DslErrorsException
(3-17)pkg/csharp/src/OpenFga.Language/OpenFgaDslErrorListener.cs (3)
OpenFgaDslErrorListener
(6-40)SyntaxError
(11-19)SyntaxError
(21-39)pkg/csharp/src/OpenFga.Language/Errors/SyntaxError.cs (3)
SyntaxError
(5-16)SyntaxError
(9-9)SyntaxError
(11-15)
pkg/csharp/src/OpenFga.Language/Errors/ValidationError.cs (1)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)
pkg/csharp/src/OpenFga.Language/ModFileArrayProperty.cs (4)
pkg/csharp/src/OpenFga.Language/ModFileStringProperty.cs (1)
ModFileStringProperty
(6-15)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (2)
StartEnd
(27-32)StartEnd
(34-39)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (4)
StartEnd
(6-37)StartEnd
(16-16)StartEnd
(18-21)StartEnd
(23-25)pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs (2)
StartEnd
(165-168)StartEnd
(170-181)
pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs (1)
pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (6)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)
pkg/csharp/test/OpenFga.Language.Tests/ModelValidatorShould.cs (6)
pkg/csharp/src/OpenFga.Language/Json.cs (1)
Json
(6-24)pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (7)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)TestsData
(5-90)pkg/csharp/src/OpenFga.Language/Errors/ModelValidationSingleError.cs (3)
ModelValidationSingleError
(6-17)ModelValidationSingleError
(11-11)ModelValidationSingleError
(13-16)pkg/csharp/src/OpenFga.Language/Validation/ModelValidator.cs (6)
ModelValidator
(6-519)ModelValidator
(15-20)ValidateDsl
(30-32)ValidateDsl
(34-44)ValidateJson
(22-24)ValidateJson
(26-28)pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs (1)
DslErrorsException
(3-17)pkg/csharp/src/OpenFga.Language/Errors/ParsingError.cs (3)
ParsingError
(6-44)ParsingError
(19-19)ParsingError
(21-25)
pkg/csharp/src/OpenFga.Language/Validation/Validator.cs (1)
pkg/csharp/src/OpenFga.Language/Validation/ValidationRegex.cs (4)
ValidationRegex
(5-32)ValidationRegex
(9-12)ValidationRegex
(17-27)Matches
(29-31)
pkg/csharp/test/OpenFga.Language.Tests/util/FgaModTestCase.cs (3)
pkg/csharp/test/OpenFga.Language.Tests/util/TestsData.cs (6)
List
(23-48)List
(50-56)List
(58-62)List
(64-68)List
(70-74)List
(76-80)pkg/csharp/test/OpenFga.Language.Tests/util/YamlHelper.cs (1)
List
(7-11)pkg/csharp/src/OpenFga.Language/Errors/ModFileValidationSingleError.cs (3)
ModFileValidationSingleError
(3-9)ModFileValidationSingleError
(5-5)ModFileValidationSingleError
(7-8)
pkg/csharp/src/OpenFga.Language/Validation/ValidationErrorsBuilder.cs (7)
pkg/java/src/main/java/dev/openfga/language/validation/ValidationErrorsBuilder.java (1)
ValidationErrorsBuilder
(10-240)pkg/csharp/src/OpenFga.Language/Errors/ModelValidationSingleError.cs (3)
ModelValidationSingleError
(6-17)ModelValidationSingleError
(11-11)ModelValidationSingleError
(13-16)pkg/csharp/src/OpenFga.Language/Errors/ErrorProperties.cs (3)
ErrorProperties
(3-24)ErrorProperties
(8-8)ErrorProperties
(10-14)pkg/csharp/src/OpenFga.Language/Errors/StartEnd.cs (4)
StartEnd
(6-37)StartEnd
(16-16)StartEnd
(18-21)StartEnd
(23-25)pkg/csharp/src/OpenFga.Language/Errors/ValidationMetadata.cs (4)
ValidationMetadata
(6-41)ValidationMetadata
(27-27)ValidationMetadata
(29-32)ValidationMetadata
(34-40)pkg/csharp/src/OpenFga.Language/Validation/Keyword.cs (1)
Keyword
(3-7)pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs (1)
DslErrorsException
(3-17)
🪛 checkmake (0.2.2)
pkg/csharp/Makefile
[warning] 1-1: Missing required phony target "all"
(minphony)
[warning] 1-1: Missing required phony target "clean"
(minphony)
[warning] 1-1: Missing required phony target "test"
(minphony)
[warning] 1-1: Target "all" should be declared PHONY.
(phonydeclared)
🪛 markdownlint-cli2 (0.18.1)
pkg/csharp/README.md
1-1: No space inside hashes on closed atx style heading
(MD020, no-missing-space-closed-atx)
public class DslErrorsException(IEnumerable<ParsingError> errors) | ||
: Exception(MessagesFromErrors(errors)) { | ||
|
||
public IReadOnlyList<ParsingError> Errors { get; } = errors.ToList().AsReadOnly(); | ||
|
||
private static string MessagesFromErrors(IEnumerable<ParsingError> errors) { | ||
var delimiter = "\n\t* "; | ||
var errorsCount = errors.Count(); | ||
var errorsPlural = errorsCount > 1 ? "s" : ""; | ||
var prefix = $"{errorsCount} error{errorsPlural} occurred:{delimiter}"; | ||
var suffix = "\n\n"; | ||
|
||
return prefix + string.Join("\n\t* ", errors.Select(e => e.ToString())) + suffix; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard against null errors
input
If callers accidentally pass a null enumerable, this implementation blows up with a NullReferenceException
inside errors.ToList()
. We should fail fast with a clear ArgumentNullException
(and reuse this verified enumerable for both the message and stored list) to avoid obscure runtime crashes.
+using System;
+
namespace OpenFga.Language.Errors;
-public class DslErrorsException(IEnumerable<ParsingError> errors)
- : Exception(MessagesFromErrors(errors)) {
-
- public IReadOnlyList<ParsingError> Errors { get; } = errors.ToList().AsReadOnly();
+public class DslErrorsException : Exception {
+ public IReadOnlyList<ParsingError> Errors { get; }
+
+ public DslErrorsException(IEnumerable<ParsingError> errors)
+ : base(MessagesFromErrors(errors ?? throw new ArgumentNullException(nameof(errors)))) {
+ ArgumentNullException.ThrowIfNull(errors);
+ Errors = errors.ToList().AsReadOnly();
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public class DslErrorsException(IEnumerable<ParsingError> errors) | |
: Exception(MessagesFromErrors(errors)) { | |
public IReadOnlyList<ParsingError> Errors { get; } = errors.ToList().AsReadOnly(); | |
private static string MessagesFromErrors(IEnumerable<ParsingError> errors) { | |
var delimiter = "\n\t* "; | |
var errorsCount = errors.Count(); | |
var errorsPlural = errorsCount > 1 ? "s" : ""; | |
var prefix = $"{errorsCount} error{errorsPlural} occurred:{delimiter}"; | |
var suffix = "\n\n"; | |
return prefix + string.Join("\n\t* ", errors.Select(e => e.ToString())) + suffix; | |
} | |
using System; | |
namespace OpenFga.Language.Errors; | |
public class DslErrorsException : Exception { | |
public IReadOnlyList<ParsingError> Errors { get; } | |
public DslErrorsException(IEnumerable<ParsingError> errors) | |
: base(MessagesFromErrors(errors ?? throw new ArgumentNullException(nameof(errors)))) { | |
ArgumentNullException.ThrowIfNull(errors); | |
Errors = errors.ToList().AsReadOnly(); | |
} | |
private static string MessagesFromErrors(IEnumerable<ParsingError> errors) { | |
var delimiter = "\n\t* "; | |
var errorsCount = errors.Count(); | |
var errorsPlural = errorsCount > 1 ? "s" : ""; | |
var prefix = $"{errorsCount} error{errorsPlural} occurred:{delimiter}"; | |
var suffix = "\n\n"; | |
return prefix + string.Join("\n\t* ", errors.Select(e => e.ToString())) + suffix; | |
} | |
} |
🤖 Prompt for AI Agents
In pkg/csharp/src/OpenFga.Language/Errors/DslErrorsException.cs around lines 3
to 16, the constructor and property assume the incoming
IEnumerable<ParsingError> errors is non-null and call errors.ToList(), which
will throw a NullReferenceException; validate errors at the start, throw an
ArgumentNullException if null, then call ToList() once into a local variable and
reuse that List to build the message and to initialize the Errors IReadOnlyList
property so the same verified enumerable is used consistently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, this is taken 1 to 1 from java, which has the same issue. Question to the reviewers what the solution should be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
@LunicLynx, I can help provide context for the reviewers. Let me check the Java implementation to see how it handles this scenario.
🏁 Script executed:
#!/bin/bash
# Check the Java DslErrorsException implementation
cat pkg/java/src/main/java/dev/openfga/language/errors/DslErrorsException.java
Length of output: 411
@LunicLynx, you're correct—the Java implementation has the same issue. Here's what I found:
Java implementation (pkg/java/src/main/java/dev/openfga/language/errors/DslErrorsException.java
):
public DslErrorsException(List<? extends ParsingError> errors) {
super(Errors.messagesFromErrors(errors));
this.errors = errors;
}
It also lacks null validation and would fail if errors
is null.
Recommendation for reviewers:
The suggested fix (adding ArgumentNullException
guard) is the idiomatic C# approach for parameter validation. However, you have a few options:
-
Apply the defensive fix (recommended): Add the null check as suggested, which prevents runtime crashes with a clear error message. This is standard practice in C# libraries.
-
Cross-language consistency: If you fix it in C#, consider opening an issue to fix the Java implementation as well with a corresponding
Objects.requireNonNull(errors, "errors")
check. -
Document the precondition: Alternatively, document that
errors
must be non-null as a precondition, though this is less safe than explicit validation.
Given that this is a public API and defensive programming is a best practice, I'd recommend accepting the suggested fix. The guard is lightweight, prevents cryptic NullReferenceExceptions, and makes the API more robust.
Would you like me to create a follow-up issue for the Java implementation if you decide to apply this fix?
var genericTypeName = | ||
ParseTypeName(context.parameterType().CONDITION_PARAM_TYPE().GetText()); | ||
if (genericTypeName != (TypeName)13) { | ||
conditionParamTypeRef.GenericTypes = | ||
[ | ||
new ConditionParamTypeRef() | ||
{ | ||
TypeName = genericTypeName | ||
} | ||
]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove magic enum number check
genericTypeName != (TypeName)13 is brittle. Use a named enum member or always add the parsed generic type if present.
- var genericTypeName =
- ParseTypeName(context.parameterType().CONDITION_PARAM_TYPE().GetText());
- if (genericTypeName != (TypeName)13) {
- conditionParamTypeRef.GenericTypes =
- [
- new ConditionParamTypeRef()
- {
- TypeName = genericTypeName
- }
- ];
- }
+ var genericType = ParseTypeName(context.parameterType().CONDITION_PARAM_TYPE().GetText());
+ conditionParamTypeRef.GenericTypes =
+ [
+ new ConditionParamTypeRef { TypeName = genericType }
+ ];
If certain sentinel (e.g., Any/Unknown) must be excluded, compare against that named enum explicitly.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
var genericTypeName = | |
ParseTypeName(context.parameterType().CONDITION_PARAM_TYPE().GetText()); | |
if (genericTypeName != (TypeName)13) { | |
conditionParamTypeRef.GenericTypes = | |
[ | |
new ConditionParamTypeRef() | |
{ | |
TypeName = genericTypeName | |
} | |
]; | |
} | |
var genericType = ParseTypeName(context.parameterType().CONDITION_PARAM_TYPE().GetText()); | |
conditionParamTypeRef.GenericTypes = | |
[ | |
new ConditionParamTypeRef { TypeName = genericType } | |
]; |
🤖 Prompt for AI Agents
In pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs around lines 171 to
181, the code currently compares genericTypeName to the magic numeric cast
(TypeName)13; replace this brittle check by either comparing to the explicit
named enum member that represents the sentinel (e.g., TypeName.Unknown or
TypeName.Any) or by using a presence check on the parsed generic type (e.g., if
genericTypeName != default(TypeName) or if genericTypeName.IsValid()/HasValue),
and then add the parsed type to conditionParamTypeRef.GenericTypes only when the
named sentinel is not matched or the parsed type is present. Ensure you use the
meaningful enum identifier instead of the numeric literal and add a brief
comment explaining why that sentinel is excluded if applicable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The enum belongs to the OpenFga.Sdk assembly. It does not define a value for 13, which is the one used in the java implementation.
The fix being proposed here would break the test, otherwise I agree with everything being said.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find the ParseTypeName method implementation to understand what it returns
ast-grep --pattern $'ParseTypeName($$$) {
$$$
}'
# Also search for it as a method definition
rg -n -A 10 "ParseTypeName" pkg/csharp/src/OpenFga.Language/
# Check the Java implementation for comparison
rg -n -A 5 "genericTypeName" pkg/java/src/main/java/dev/openfga/language/ -C 3
# Find test cases related to condition parameters to understand expected behavior
rg -n "CONDITION_PARAM" pkg/csharp/test/ -A 3 -B 3
Length of output: 4671
🏁 Script executed:
#!/bin/bash
# Check if TypeName is referenced elsewhere in C# code
rg -n "TypeName" pkg/csharp/src/OpenFga.Language/ -C 2
# Look for any enum value definitions or constants related to TypeName
rg -n "TypeName\." pkg/csharp/ -C 1
# Check test files to see what breaks with the proposed change
rg -n "genericType" pkg/csharp/test/ -A 5 -B 5
# Look for condition parameter test cases
fd -e json -e yaml . pkg/csharp/test/ -x cat {} | head -100
Length of output: 11669
@LunicLynx, thank you for the clarification! You're absolutely right—since the OpenFga.Sdk
assembly doesn't define a named constant for value 13 (equivalent to Java's TypeName.UNKNOWN_DEFAULT_OPEN_API
), we need to work with what's available while improving code clarity.
Here's a recommended approach that maintains test compatibility while documenting the intent:
// Add at class level:
/// <summary>
/// Sentinel value representing an unknown/invalid type name parsed from DSL.
/// Corresponds to TypeName.UNKNOWN_DEFAULT_OPEN_API in the Java SDK.
/// This value (13) is not defined in the OpenFga.Sdk TypeName enum but is used
/// to filter out invalid generic types during parsing.
/// </summary>
private const int UnknownTypeNameSentinel = 13;
// Then update the check:
if (context.parameterType().CONDITION_PARAM_TYPE() != null) {
var genericTypeName =
ParseTypeName(context.parameterType().CONDITION_PARAM_TYPE().GetText());
// Skip adding generic types that failed to parse (result in unknown sentinel)
if (genericTypeName != (TypeName)UnknownTypeNameSentinel) {
conditionParamTypeRef.GenericTypes =
[
new ConditionParamTypeRef()
{
TypeName = genericTypeName
}
];
}
}
This approach:
- Documents the magic number's purpose
- References the Java implementation for maintainability
- Preserves existing test behavior
- Makes future code reviews clearer
Would you like me to help draft a similar comment pattern for any other translation-specific workarounds in the codebase?
namespace OpenFga.Language; | ||
|
||
class PartialRelationReference { | ||
public string? Type { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider making Type
required or add validation.
The Type
property is nullable but is asserted non-null on Line 13 using the null-forgiving operator. This creates a risk of NullReferenceException
at runtime if Type
is null when AsRelationReference()
is called.
Apply this diff to make Type
required:
- public string? Type { get; set; }
+ public required string Type { get; set; }
Alternatively, add validation in AsRelationReference()
:
public RelationReference AsRelationReference() {
+ if (Type == null) {
+ throw new InvalidOperationException("Type is required");
+ }
return new RelationReference() {
- Type = Type!,
+ Type = Type,
Relation = Relation,
Wildcard = Wildcard,
Condition = Condition,
};
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
public string? Type { get; set; } | |
// pkg/csharp/src/OpenFga.Language/PartialRelationReference.cs | |
namespace OpenFga.Language | |
{ | |
internal class PartialRelationReference | |
{ | |
public required string Type { get; set; } | |
public string? Relation { get; set; } | |
public object? Wildcard { get; set; } | |
public string? Condition { get; set; } | |
public RelationReference AsRelationReference() { | |
if (Type == null) { | |
throw new InvalidOperationException("Type is required"); | |
} | |
return new RelationReference() { | |
Type = Type, | |
Relation = Relation, | |
Wildcard = Wildcard, | |
Condition = Condition, | |
}; | |
} | |
} | |
} |
🤖 Prompt for AI Agents
In pkg/csharp/src/OpenFga.Language/PartialRelationReference.cs around line 6,
the property "public string? Type { get; set; }" is nullable but is later
asserted non-null in AsRelationReference(), risking a NullReferenceException;
fix by either making the property non-nullable (remove the '?') so the compiler
enforces assignment, or keep it nullable and add a runtime null check in
AsRelationReference() that throws a clear ArgumentNullException or returns an
appropriate error if Type is null before using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but this is an issue in the Java implementation as well. I was not sure I should go for all the nullable adjustements, specifically as the tests can't be reused when OpenFga.Sdk respects nullable for serialization.
Not sure what makes the most sense here. In general I think nullable should be utilized as much as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LunicLynx, I understand your concern about balancing C# best practices with cross-language consistency and test compatibility.
Given your constraints, here's a pragmatic approach:
For this PR (maintaining Java parity):
Keep the nullable Type
property as-is since you're translating from Java. However, add a defensive null check in AsRelationReference()
to fail fast with a clear error message:
public RelationReference AsRelationReference() {
if (Type == null) {
throw new InvalidOperationException("Type cannot be null when creating RelationReference");
}
return new RelationReference() {
Type = Type,
Relation = Relation,
Wildcard = Wildcard,
Condition = Condition,
};
}
This provides safety without breaking serialization behavior or test compatibility.
For future improvements:
Consider opening a follow-up issue to:
- Review nullable handling across both Java and C# implementations
- Evaluate making
Type
required (usingrequired
modifier) once you've verified SDK serialization compatibility - Update shared test data if needed
This approach gives you immediate safety while deferring the broader nullable strategy to a dedicated effort where you can properly test the serialization implications.
Would you like me to open a follow-up issue to track the nullable improvements for later?
var type = DestructuredTupleToUserset.From(item); | ||
var decodedType = type.DecodedType; | ||
if (!typeMap.ContainsKey(decodedType)) { | ||
var typeIndex = _dsl.GetTypeLineNumber(typeName); | ||
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | ||
_errors.RaiseInvalidType(lineIndex, decodedType, decodedType); | ||
} | ||
|
||
var decodedConditionName = type.DecodedConditionName; | ||
if (decodedConditionName != null && !(_authorizationModel.Conditions?.ContainsKey(decodedConditionName) ?? false)) { | ||
var typeIndex = _dsl.GetTypeLineNumber(typeName); | ||
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | ||
_errors.RaiseInvalidConditionNameInParameter( | ||
lineIndex, decodedConditionName, typeName, relationName, decodedConditionName); | ||
} | ||
|
||
var decodedRelation = type.DecodedRelation; | ||
if (type.IsWildcard && decodedRelation != null) { | ||
var typeIndex = _dsl.GetTypeLineNumber(typeName); | ||
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | ||
_errors.RaiseAssignableTypeWildcardRelation(lineIndex, item); | ||
} | ||
else if (decodedRelation != null) { | ||
if (typeMap[decodedType] == null || !typeMap[decodedType].Relations!.ContainsKey(decodedRelation)) { | ||
var typeIndex = _dsl.GetTypeLineNumber(typeName); | ||
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | ||
_errors.RaiseInvalidTypeRelation( | ||
lineIndex, decodedType + "#" + decodedRelation, decodedType, decodedRelation); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard against missing types to avoid KeyNotFoundException
When decodedType is absent in typeMap, you raise InvalidType but still index typeMap[decodedType] later, which will throw.
- if (!typeMap.ContainsKey(decodedType)) {
- var typeIndex = _dsl.GetTypeLineNumber(typeName);
- var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex);
- _errors.RaiseInvalidType(lineIndex, decodedType, decodedType);
- }
+ if (!typeMap.ContainsKey(decodedType)) {
+ var typeIndex = _dsl.GetTypeLineNumber(typeName);
+ var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex);
+ _errors.RaiseInvalidType(lineIndex, decodedType, decodedType);
+ continue; // avoid indexing a missing key below
+ }
...
- else if (decodedRelation != null) {
- if (typeMap[decodedType] == null || !typeMap[decodedType].Relations!.ContainsKey(decodedRelation)) {
+ else if (decodedRelation != null) {
+ var decodedTypeDef = typeMap[decodedType];
+ if (decodedTypeDef.Relations == null || !decodedTypeDef.Relations.ContainsKey(decodedRelation)) {
var typeIndex = _dsl.GetTypeLineNumber(typeName);
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex);
_errors.RaiseInvalidTypeRelation(
lineIndex, decodedType + "#" + decodedRelation, decodedType, decodedRelation);
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
var type = DestructuredTupleToUserset.From(item); | |
var decodedType = type.DecodedType; | |
if (!typeMap.ContainsKey(decodedType)) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseInvalidType(lineIndex, decodedType, decodedType); | |
} | |
var decodedConditionName = type.DecodedConditionName; | |
if (decodedConditionName != null && !(_authorizationModel.Conditions?.ContainsKey(decodedConditionName) ?? false)) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseInvalidConditionNameInParameter( | |
lineIndex, decodedConditionName, typeName, relationName, decodedConditionName); | |
} | |
var decodedRelation = type.DecodedRelation; | |
if (type.IsWildcard && decodedRelation != null) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseAssignableTypeWildcardRelation(lineIndex, item); | |
} | |
else if (decodedRelation != null) { | |
if (typeMap[decodedType] == null || !typeMap[decodedType].Relations!.ContainsKey(decodedRelation)) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseInvalidTypeRelation( | |
lineIndex, decodedType + "#" + decodedRelation, decodedType, decodedRelation); | |
} | |
} | |
var type = DestructuredTupleToUserset.From(item); | |
var decodedType = type.DecodedType; | |
if (!typeMap.ContainsKey(decodedType)) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseInvalidType(lineIndex, decodedType, decodedType); | |
continue; // avoid indexing a missing key below | |
} | |
var decodedConditionName = type.DecodedConditionName; | |
if (decodedConditionName != null && !(_authorizationModel.Conditions?.ContainsKey(decodedConditionName) ?? false)) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseInvalidConditionNameInParameter( | |
lineIndex, decodedConditionName, typeName, relationName, decodedConditionName); | |
} | |
var decodedRelation = type.DecodedRelation; | |
if (type.IsWildcard && decodedRelation != null) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseAssignableTypeWildcardRelation(lineIndex, item); | |
} | |
else if (decodedRelation != null) { | |
var decodedTypeDef = typeMap[decodedType]; | |
if (decodedTypeDef.Relations == null || !decodedTypeDef.Relations.ContainsKey(decodedRelation)) { | |
var typeIndex = _dsl.GetTypeLineNumber(typeName); | |
var lineIndex = _dsl.GetRelationLineNumber(relationName, typeIndex); | |
_errors.RaiseInvalidTypeRelation( | |
lineIndex, decodedType + "#" + decodedRelation, decodedType, decodedRelation); | |
} | |
} |
pkg/java/src/main/java/dev/openfga/language/validation/ValidationErrorsBuilder.java
Outdated
Show resolved
Hide resolved
pkg/java/src/main/java/dev/openfga/language/JsonToDslTransformer.java
Outdated
Show resolved
Hide resolved
Nice! Thanks @LunicLynx! Wonderful effort! Will discuss this w/ the other maintainers to make sure they're all good & comfortable with this before merging. If merged, safe to say the ID of this will be When ready, for your PR, we may also want to:
Long term, we may also want to support .NET Standard 2.0 to match our SDK support, but I would leave that until folks ask for it. Will do a proper review over the weekend |
<TargetFrameworks>net8.0;net9.0</TargetFrameworks> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<Authors>OpenFGA; Florian Dohrendorf</Authors> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to remove my name here if personal attribution is not the way to go.
* Add dependabot outline * Set Package name * Correct usage of using
Ok I'll leave it like this for now. Tried my best with dependabot by utilizing AI. Never used dependabot so I'm not sure what it did is correct. |
Hello @rhamzeh, thanks for the welcoming hello! Let me know to which degree I should address the notes from the coderabbitai or in which other way I can make this review less painful for you. I could also do another pass to workout better nullable handling in C#, the reason why I choose the current approach was mainly to keep the tests working as they are right now. |
Description
C# Implementation based on java version in this repository.
What problem is being solved?
Feature parity for C#
How is it being solved?
Translation from Java to C# making all tests succeed.
Closes #501
Review Checklist
main
Summary by CodeRabbit