public void WriteExtensibleEnum()

in src/AutoRest.CSharp/Common/Generation/Writers/ModelWriter.cs [369:478]


        public void WriteExtensibleEnum(CodeWriter writer, EnumType enumType)
        {
            var cs = enumType.Type;
            string name = enumType.Declaration.Name;
            var valueType = enumType.ValueType;
            var isString = valueType.FrameworkType == typeof(string);

            using (writer.Namespace(enumType.Declaration.Namespace))
            {
                writer.WriteXmlDocumentationSummary($"{enumType.Description}");
                AddClassAttributes(writer, enumType);

                var implementType = new CSharpType(typeof(IEquatable<>), cs);
                using (writer.Scope($"{enumType.Declaration.Accessibility} readonly partial struct {name}: {implementType}"))
                {
                    writer.Line($"private readonly {valueType} _value;");
                    writer.Line();

                    writer.WriteXmlDocumentationSummary($"Initializes a new instance of {name:C}.");

                    if (isString)
                    {
                        writer.WriteXmlDocumentationException(typeof(ArgumentNullException), $"<paramref name=\"value\"/> is null.");
                    }

                    using (writer.Scope($"public {name}({valueType} value)"))
                    {
                        writer.Append($"_value = value");
                        if (isString)
                        {
                            writer.Append($"?? throw new {typeof(ArgumentNullException)}(nameof(value))");
                        }
                        writer.Line($";");
                    }
                    writer.Line();

                    foreach (var choice in enumType.Values)
                    {
                        var fieldName = GetValueFieldName(name, choice.Declaration.Name, enumType.Values);
                        writer.Line($"private const {valueType} {fieldName} = {choice.Value.Value:L};");
                    }
                    writer.Line();

                    foreach (var choice in enumType.Values)
                    {
                        writer.WriteXmlDocumentationSummary($"{choice.Description}");
                        var fieldName = GetValueFieldName(name, choice.Declaration.Name, enumType.Values);
                        writer.Append($"public static {cs} {choice.Declaration.Name}").AppendRaw("{ get; }").Append($" = new {cs}({fieldName});").Line();
                    }

                    // write ToSerial method, only write when the underlying type is not a string
                    if (!enumType.IsStringValueType)
                    {
                        writer.Line();
                        writer.Line($"internal {valueType} {enumType.SerializationMethodName}() => _value;");
                        writer.Line();
                    }

                    writer.WriteXmlDocumentationSummary($"Determines if two {name:C} values are the same.");
                    writer.Line($"public static bool operator ==({cs} left, {cs} right) => left.Equals(right);");

                    writer.WriteXmlDocumentationSummary($"Determines if two {name:C} values are not the same.");
                    writer.Line($"public static bool operator !=({cs} left, {cs} right) => !left.Equals(right);");

                    writer.WriteXmlDocumentationSummary($"Converts a {valueType:C} to a {name:C}.");
                    writer.Line($"public static implicit operator {cs}({valueType} value) => new {cs}(value);");
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    WriteEditorBrowsableFalse(writer);
                    writer.Line($"public override bool Equals({typeof(object)} obj) => obj is {cs} other && Equals(other);");

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Append($"public bool Equals({cs} other) => ");
                    if (isString)
                    {
                        writer.Line($"{valueType}.Equals(_value, other._value, {typeof(StringComparison)}.InvariantCultureIgnoreCase);");
                    }
                    else
                    {
                        writer.Line($"{valueType}.Equals(_value, other._value);");
                    }
                    writer.Line();

                    writer.WriteXmlDocumentationInheritDoc();
                    WriteEditorBrowsableFalse(writer);
                    writer.Append($"public override int GetHashCode() => ");
                    if (isString)
                    {
                        writer.Line($"_value != null ? {typeof(StringComparer)}.InvariantCultureIgnoreCase.GetHashCode(_value) : 0;");
                    }
                    else
                    {
                        writer.Line($"_value.GetHashCode();");
                    }

                    writer.WriteXmlDocumentationInheritDoc();
                    writer.Append($"public override {typeof(string)} ToString() => ");

                    if (isString)
                    {
                        writer.Line($"_value;");
                    }
                    else
                    {
                        writer.Line($"_value.ToString({typeof(CultureInfo)}.InvariantCulture);");
                    }
                }
            }
        }