Skip to content

Conversation

LunicLynx
Copy link

@LunicLynx LunicLynx commented Oct 3, 2025

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

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

Summary by CodeRabbit

  • New Features
    • Added C# support for the OpenFGA Language: DSL↔JSON transformers, mod file (.fga.mod) to JSON conversion, and model/DSL validation for .NET (multi-targeted).
  • Bug Fixes
    • Java: Prevented a null-pointer in condition formatting during JSON→DSL.
    • Java: Improved error position detection for validation messages.
  • Documentation
    • Updated README to include C#; added C# usage guide with examples.
  • Chores
    • Extended build system with C# targets; added solution, configuration, and comprehensive C# test suite.

@LunicLynx LunicLynx requested review from a team as code owners October 3, 2025 17:54
Copy link

linux-foundation-easycla bot commented Oct 3, 2025

CLA Signed

The committers listed above are authorized under a signed CLA.

Copy link

coderabbitai bot commented Oct 3, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds 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

Cohort / File(s) Summary
Build and tooling
Makefile, pkg/csharp/Makefile, pkg/csharp/.editorconfig, pkg/csharp/.gitignore, pkg/csharp/OpenFga.Language.slnx, pkg/csharp/OpenFga.Language.sln.DotSettings.user
Adds C# targets to global workflow; introduces C# project/editor configs, gitignore, solution and IDE settings; standard build/test/lint/format targets for C#.
Repo docs
README.md, pkg/csharp/README.md
Documents C# support; adds C# usage for transformers, mod parsing, and validation.
C# project
pkg/csharp/src/OpenFga.Language/OpenFga.Language.csproj
New multi-targeted .NET project with package metadata and dependencies (Antlr4, OpenFga.Sdk, SharpYaml).
DSL→JSON transformer
pkg/csharp/src/OpenFga.Language/DslToJsonTransformer.cs, pkg/csharp/src/OpenFga.Language/OpenFgaDslListener.cs, pkg/csharp/src/OpenFga.Language/OpenFgaDslErrorListener.cs, pkg/csharp/src/OpenFga.Language/Relation.cs, pkg/csharp/src/OpenFga.Language/StackRelation.cs, pkg/csharp/src/OpenFga.Language/PartialRelationReference.cs, pkg/csharp/src/OpenFga.Language/Json.cs
Implements DSL parsing with ANTLR, error listener, parse-tree listener to build AuthorizationModel, intermediate relation structures, and JSON helpers.
JSON→DSL transformer
pkg/csharp/src/OpenFga.Language/JsonToDslTransformer.cs, pkg/csharp/src/OpenFga.Language/PartialConditionParamTypeRef.cs, pkg/csharp/src/OpenFga.Language/Utils.cs, pkg/csharp/src/OpenFga.Language/Utils/ModelUtils.cs
Converts AuthorizationModel to DSL; adds helpers for condition types, deep copy, module lookup, and assignability checks.
Mod file parsing
pkg/csharp/src/OpenFga.Language/FgaModTransformer.cs, pkg/csharp/src/OpenFga.Language/FgaModFile.cs, pkg/csharp/src/OpenFga.Language/ModFileArrayProperty.cs, pkg/csharp/src/OpenFga.Language/ModFileStringProperty.cs
Parses FGA mod content into structured model with validation and location-aware errors; data models for schema/contents with line/column metadata.
Error models and exceptions
pkg/csharp/src/OpenFga.Language/Errors/*
Adds structured error hierarchy (SimpleError, ParsingError, Syntax/Validation variants), metadata types, enums, positions (StartEnd), and exceptions for DSL/mod validation and unsupported nesting.
Validation core
pkg/csharp/src/OpenFga.Language/Validation/*
Introduces model validator, regex/rule utilities, error aggregation/builder, DSL line helpers, relation parsing helpers, tuple destructuring, rewrite types, and internal result containers.
C# tests
pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csproj, pkg/csharp/test/OpenFga.Language.Tests/*.cs, pkg/csharp/test/OpenFga.Language.Tests/util/*
Adds unit tests for transformers, mod parsing, model validation, and utilities; test data loaders and YAML helpers.
Java adjustments
pkg/java/src/main/java/dev/openfga/language/JsonToDslTransformer.java, pkg/java/src/main/java/dev/openfga/language/validation/ValidationErrorsBuilder.java
Null-guard in conditions formatting; improves regex for symbol matching in error positioning.
Test data updates
tests/data/json-validation-cases.yaml, tests/data/transformer/11-multiple-conditions/authorization-model.json
Adds/adjusts expected validation errors and consolidates condition definitions in transformer test data.

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
Loading
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
Loading
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
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.24% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title succinctly communicates the addition of a C# implementation based on the existing Java implementation and directly reflects the primary change, making it clear to reviewers and maintainers.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

socket-security bot commented Oct 3, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednuget/​xunit.runner.visualstudio@​2.5.39210089100100
Addednuget/​xunit@​2.6.110010089100100
Addednuget/​microsoft.net.test.sdk@​17.8.010010090100100
Addednuget/​antlr4.runtime.standard@​4.13.19910090100100
Addednuget/​sharpyaml@​2.1.39910090100100
Addednuget/​openfga.sdk@​0.7.09610090100100

View full report

Copy link

socket-security bot commented Oct 3, 2025

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.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: HP-1989 (THIRD-PARTY-NOTICES.TXT)

License: Unicode-3.0 (THIRD-PARTY-NOTICES.TXT)

License: W3C-20150513 (THIRD-PARTY-NOTICES.TXT)

From: pkg/csharp/src/OpenFga.Language/OpenFga.Language.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (dotnet_library_license.txt)

License: ms-net-library (Microsoft.NETCore.Platforms.nuspec)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (dotnet_library_license.txt)

License: ms-net-library (Microsoft.NETCore.Targets.nuspec)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (Microsoft.Win32.Primitives.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (dotnet_library_license.txt)

License: ms-net-library (NETStandard.Library.nuspec)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl@4.3.0 has a License Policy Violation.

License: ms-net-library (runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl@4.3.0

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/runtime.debian.8-x64.runtime.native.system.security.cryptography.openssl@4.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/runtime.fedora.23-x64.runtime.native.system.security.cryptography.openssl@4.3.0 has a License Policy Violation.

License: ms-net-library (runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/runtime.fedora.23-x64.runtime.native.system.security.cryptography.openssl@4.3.0

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/runtime.fedora.23-x64.runtime.native.system.security.cryptography.openssl@4.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/runtime.fedora.24-x64.runtime.native.system.security.cryptography.openssl@4.3.0 has a License Policy Violation.

License: ms-net-library (runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/runtime.fedora.24-x64.runtime.native.system.security.cryptography.openssl@4.3.0

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/runtime.fedora.24-x64.runtime.native.system.security.cryptography.openssl@4.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (runtime.native.System.IO.Compression.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (runtime.native.System.Net.Http.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (runtime.native.System.Security.Cryptography.Apple.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
nuget/[email protected] has a License Policy Violation.

License: ms-net-library (runtime.native.System.Security.Cryptography.OpenSsl.nuspec)

License: ms-net-library (dotnet_library_license.txt)

From: pkg/csharp/test/OpenFga.Language.Tests/OpenFga.Language.Tests.csprojnuget/[email protected]nuget/[email protected]

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at [email protected].

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore nuget/[email protected]. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

See 65 more rows in the dashboard

View full report

@rhamzeh rhamzeh changed the title C# implementation based on the Java implementation feat: C# implementation based on the Java implementation Oct 3, 2025
if (lines != null) {
var rawLine = lines[lineIndex];
var regex = Pattern.compile("\\b" + symbol + "\\b");
var regex = Pattern.compile("\\b" + Pattern.quote(symbol) + "((?=\\W)|$)");
Copy link
Author

@LunicLynx LunicLynx Oct 3, 2025

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.

Copy link

@coderabbitai coderabbitai bot left a 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 prevent NullReferenceException if Type 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 mutable List<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 passes null for records, or if any value in the dictionary is null, the method will throw a NullReferenceException.

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 ensure TypeName is always set
  • Make properties read-only after construction to prevent unintended mutations
  • Add validation if certain TypeName values or null GenericTypes elements are invalid

Example 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 new ConditionParamTypeRef. If the list is later modified through the original PartialConditionParamTypeRef 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 to null 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 (!) on testCase.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 uses IEnumerable<object> as the parameter type, but it only receives List<ModFileValidationSingleError> from the constructor. Using IEnumerable<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" and T constructor requirement

  • Parse<T> treats the four-character literal "null" like empty or null, returning new T(). Consider returning null instead or documenting this behavior to avoid surprises.
  • Verified FgaModFile and AuthorizationModel have implicit public parameterless constructors, so Activator.CreateInstance<T>() succeeds. Document that T must expose a public parameterless constructor.
pkg/csharp/src/OpenFga.Language/Validation/Validator.cs (3)

16-21: Mislabelled regex names degrade error messages

ObjectId/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 static

All members are static; declare the class static.

-public class Validator {
+public static class Validator {

41-43: ValidateObject may be over-restrictive

Requiring 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 discovery

DirectoryInfo.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().Location

Simpler 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 naming

Hardcoding "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 typeName

Avoid 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 keying

SourceInfo.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 code

Patterns like ?? [] and foreach (... ?? []) 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

📥 Commits

Reviewing files that changed from the base of the PR and between 02ef40c and d690efa.

⛔ 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)

Comment on lines 3 to 16
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;
}
Copy link

@coderabbitai coderabbitai bot Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Copy link
Author

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?

Copy link

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:

  1. 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.

  2. 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.

  3. 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?

Comment on lines +171 to +181
var genericTypeName =
ParseTypeName(context.parameterType().CONDITION_PARAM_TYPE().GetText());
if (genericTypeName != (TypeName)13) {
conditionParamTypeRef.GenericTypes =
[
new ConditionParamTypeRef()
{
TypeName = genericTypeName
}
];
}
Copy link

@coderabbitai coderabbitai bot Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Copy link
Author

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.

Copy link

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; }
Copy link

@coderabbitai coderabbitai bot Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Copy link
Author

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.

Copy link

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:

  1. Review nullable handling across both Java and C# implementations
  2. Evaluate making Type required (using required modifier) once you've verified SDK serialization compatibility
  3. 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?

Comment on lines +342 to +371
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);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

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.

Suggested change
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);
}
}

@rhamzeh
Copy link
Member

rhamzeh commented Oct 3, 2025

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 OpenFga.Language.

When ready, for your PR, we may also want to:

  1. Extend dependabot config to allow it to update the dependencies for the new c# dependencies.
  2. Add the .NET release workflow, it can be inspired by the existing workflows and the .NET SDK workflow - one thing to be careful about, the tag should be of the format pkg/csharp/v0.2.0-beta.1 instead of just v0.2.0-beta.1.

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>
Copy link
Author

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
* Java lint
* dependabot fails
@LunicLynx
Copy link
Author

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.

@LunicLynx
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

C# implementation of the language

2 participants