Repository: microsoft/kiota (csharp)

Issue:
Properties with leading double underscores (__) not generated properly from OpenAPI
### What are you generating using Kiota, clients or plugins?

API Client/SDK

### In what context or format are you using Kiota?

Nuget tool

### Client library/SDK language

TypeScript

### Describe the bug

When generating a TypeScript client using Kiota from an OpenAPI specification, properties that start with double underscores (e.g. __component) are not correctly generated in the resulting models or types.
This causes issues when working with APIs (like Strapi) that use such fields as discriminators for dynamic zones.

For example, in the generated code I get the following error:
`Property '__component' does not exist on type 'Partial<FridgeComponent | WashingMachineComponent>'. Did you mean 'component'?
  Property '__component' does not exist on type 'Partial<FridgeComponent>'.`

This relates to the following code fragment:
```typescript
export function serializeProductComponent(writer: SerializationWriter, productComponent: Partial<FridgeComponent | WashingMachineComponent> | undefined | null = {}) : void {
    if (productComponent === undefined || productComponent === null) return;
    switch (productComponent.__component) { //ERROR
        case "products.fridge":
            serializeFridgeComponent(writer, productComponent as FridgeComponent);
            break;
        case "products.washing-machine":
            serializeWashingMachineComponent(writer, productComponent as WashingMachineComponent);
            break;
    }
}
```
It appears that the generated types use __component instead of component, so accessing productComponent.__component results in a TypeScript error.

### Expected behavior

Properties with double underscores (e.g. __component) should be correctly generated.

### How to reproduce

Use the following OpenAPI schema with a property starting with double underscores (e.g. __component) as a discriminator and generate a client

### Open API description file
```json
{
  "openapi": "3.0.0",
  "info": {
    "title": "Strapi Example API",
    "version": "1.0.0"
  },
  "paths": {
    "/products": {
      "get": {
        "responses": {
          "200": {
            "description": "List of products",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductListResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ProductListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Product" }
          }
        }
      },
      "Product": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "title": { "type": "string" },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ProductComponent" }
          }
        }
      },
      "ProductComponent": {
        "type": "object",
        "discriminator": {
          "propertyName": "__component",
          "mapping": {
            "products.fridge": "#/components/schemas/FridgeComponent",
            "products.washing-machine": "#/components/schemas/WashingMachineComponent"
          }
        },
        "oneOf": [
          { "$ref": "#/components/schemas/FridgeComponent" },
          { "$ref": "#/components/schemas/WashingMachineComponent" }
        ]
      },
      "FridgeComponent": {
        "type": "object",
        "properties": {
          "__component": { "type": "string", "enum": ["products.fridge"] },
          "capacity": { "type": "integer", "description": "Capacity in liters" },
          "energyClass": { "type": "string" }
        }
      },
      "WashingMachineComponent": {
        "type": "object",
        "properties": {
          "__component": { "type": "string", "enum": ["products.washing-machine"] },
          "maxLoad": { "type": "integer", "description": "Max load in kg" },
          "spinSpeed": { "type": "integer", "description": "Spin speed in RPM" }
        }
      }
    }
  }
}
```

### Kiota Version

1.28.0+57130b1b1db3bc5c060498682f41e20c8ae089f2

### Latest Kiota version known to work for scenario above?(Not required)

_No response_

### Known Workarounds

_No response_

### Configuration

_No response_

### Debug output




### Other information

_No response_

Pull request:
* Use `CleanupSymbolName()` when writing the `DiscriminatorSwitchBlock`.
* Remove leading `_` in discriminators by updating the `CleanupSymbolName()`. Underscores are not part of the regex.
* Updated tests.

Fixes: https://github.com/microsoft/kiota/issues/6758
Follows suggestion: https://github.com/microsoft/kiota/pull/6764

Patch:
diff --git a/src/Kiota.Builder/Extensions/StringExtensions.cs b/src/Kiota.Builder/Extensions/StringExtensions.cs
index eb64e838e4..900863eee8 100644
--- a/src/Kiota.Builder/Extensions/StringExtensions.cs
+++ b/src/Kiota.Builder/Extensions/StringExtensions.cs
@@ -184,6 +184,7 @@ public static string CleanupSymbolName(this string? original)
 
         string result = NormalizeSymbolsBeforeCleanup(original);
 
+        result = result.TrimStart('_');
         result = propertyCleanupRegex().Replace(result,
                                 static x => x.Groups.Keys.Contains(CleanupGroupName) ?
                                                 x.Groups[CleanupGroupName].Value.ToFirstCharacterUpperCase() :
@@ -236,6 +237,7 @@ public static string CleanupSymbolName(this string? original)
         {'+', "Plus"},
         {',', "Comma"},
         {'-', "Hyphen"},
+        {'_', "Underscore"},
         {'.', "Period"},
         {'/', "Slash"},
         {'\\', "BackSlash"},
diff --git a/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs b/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs
index 44e22e600b..d4b1a9b6af 100644
--- a/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs
+++ b/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs
@@ -166,7 +166,7 @@ private void WriteBruteForceSerializationFunctionForCodeUnionType(CodeComposedTy
 
     private void WriteDiscriminatorSwitchBlock(DiscriminatorInformation discriminatorInfo, string paramName, CodeFunction codeElement, LanguageWriter writer)
     {
-        writer.StartBlock($"switch ({paramName}.{discriminatorInfo.DiscriminatorPropertyName}) {{");
+        writer.StartBlock($"switch ({paramName}.{discriminatorInfo.DiscriminatorPropertyName.CleanupSymbolName()}) {{");
 
         foreach (var mappedType in discriminatorInfo.DiscriminatorMappings)
         {


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Extensions/StringExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/StringExtensionsTests.cs
index 57f709b386..2a6b9157cd 100644
--- a/tests/Kiota.Builder.Tests/Extensions/StringExtensionsTests.cs
+++ b/tests/Kiota.Builder.Tests/Extensions/StringExtensionsTests.cs
@@ -99,6 +99,10 @@ public void NormalizeNameSpaceName()
     [InlineData("-1-1", "minus_11")]
     [InlineData("-", "minus")]
     [InlineData("@", "At")]
+    [InlineData("_component", "component")]
+    [InlineData("__component", "component")]
+    [InlineData("a__b", "a__b")]
+    [InlineData("_", "Underscore")]
     [Theory]
     public void CleansUpSymbolNames(string input, string expected)
     {
diff --git a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs
index 22c56a3566..ef59b56a42 100644
--- a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs
+++ b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs
@@ -29,7 +29,6 @@ public sealed class CodeFunctionWriterTests : IDisposable
     private const string ReturnTypeName = "Somecustomtype";
     private readonly HttpClient _httpClient = new();
     private readonly List<string> _tempFiles = new();
-    private const string IndexFileName = "index";
 
     public CodeFunctionWriterTests()
     {
@@ -1677,6 +1676,7 @@ public async Task Writes_CodeUnionBetweenObjectsAndPrimitiveTypes_DeserializerAs
 
         Assert.Contains("\"property\": n => { parentClass.property = n.getCollectionOfObjectValues<ArrayOfObjects>(createArrayOfObjectsFromDiscriminatorValue) ?? n.getNumberValue() ?? n.getObjectValue<SingleObject>(createSingleObjectFromDiscriminatorValue) ?? n.getStringValue(); }", result);
     }
+
     [Fact]
     public void WritesByteArrayPropertyDeserialization()
     {