<commit_before>using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Text;
using LanguageExt;
using System.Linq.Expressions;

namespace ExRam.Gremlinq
{
    public static class GremlinQuery
    {
        private class GremlinQueryImpl : IGremlinQuery
        {
            public GremlinQueryImpl(string graphName, IImmutableList<GremlinStep> steps, IGremlinQueryProvider provider, IImmutableDictionary<MemberInfo, string> memberInfoMappings)
            {
                this.Steps = steps;
                this.Provider = provider;
                this.GraphName = graphName;
                this.MemberInfoMappings = memberInfoMappings;
            }

            public (string queryString, IDictionary<string, object> parameters) Serialize(IParameterCache parameterCache, bool inlineParameters)
            {
                var parameters = new Dictionary<string, object>();
                var builder = new StringBuilder(this.GraphName);

                foreach (var step in this.Steps)
                {
                    var appendComma = false;

                    if (builder.Length > 0)
                        builder.Append('.');

                    builder.Append(step.Name);
                    builder.Append("(");

                    foreach (var parameter in step.Parameters)
                    {
                        if (appendComma)
                            builder.Append(", ");
                        else
                            appendComma = true;

                        if (parameter is IGremlinSerializable serializable)
                        {
                            var (innerQueryString, innerParameters) = serializable.Serialize(parameterCache, inlineParameters);
                            
                            builder.Append(innerQueryString);

                            foreach (var kvp in innerParameters)
                            {
                                parameters[kvp.Key] = kvp.Value;
                            }
                        }
                        else
                        {
                            if (parameter is string && inlineParameters)
                                builder.Append($"'{parameter}'");
                            else
                            {
                                if (inlineParameters)
                                    builder.Append(parameter);
                                else
                                {
                                    var newParameterName = parameterCache.Cache(parameter);
                                    parameters.Add(newParameterName, parameter);

                                    builder.Append(newParameterName);
                                }
                            }
                        }
                    }

                    builder.Append(")");
                }

                return (builder.ToString(), parameters);
            }

            public string GraphName { get; }
            public IGremlinQueryProvider Provider { get; }
            public IImmutableList<GremlinStep> Steps { get; }
            public IImmutableDictionary<MemberInfo, string> MemberInfoMappings { get; }
        }

        private sealed class GremlinQueryImpl<T> : GremlinQueryImpl, IGremlinQuery<T><commit_msg>Query-Serialization: Set parameters instead of adding them which will throw whenever a parameter has been cached.<commit_after>using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Text;
using LanguageExt;
using System.Linq.Expressions;

namespace ExRam.Gremlinq
{
    public static class GremlinQuery
    {
        private class GremlinQueryImpl : IGremlinQuery
        {
            public GremlinQueryImpl(string graphName, IImmutableList<GremlinStep> steps, IGremlinQueryProvider provider, IImmutableDictionary<MemberInfo, string> memberInfoMappings)
            {
                this.Steps = steps;
                this.Provider = provider;
                this.GraphName = graphName;
                this.MemberInfoMappings = memberInfoMappings;
            }

            public (string queryString, IDictionary<string, object> parameters) Serialize(IParameterCache parameterCache, bool inlineParameters)
            {
                var parameters = new Dictionary<string, object>();
                var builder = new StringBuilder(this.GraphName);

                foreach (var step in this.Steps)
                {
                    var appendComma = false;

                    if (builder.Length > 0)
                        builder.Append('.');

                    builder.Append(step.Name);
                    builder.Append("(");

                    foreach (var parameter in step.Parameters)
                    {
                        if (appendComma)
                            builder.Append(", ");
                        else
                            appendComma = true;

                        if (parameter is IGremlinSerializable serializable)
                        {
                            var (innerQueryString, innerParameters) = serializable.Serialize(parameterCache, inlineParameters);
                            
                            builder.Append(innerQueryString);

                            foreach (var kvp in innerParameters)
                            {
                                parameters[kvp.Key] = kvp.Value;
                            }
                        }
                        else
                        {
                            if (parameter is string && inlineParameters)
                                builder.Append($"'{parameter}'");
                            else
                            {
                                if (inlineParameters)
                                    builder.Append(parameter);
                                else
                                {
                                    var newParameterName = parameterCache.Cache(parameter);
                                    parameters[newParameterName] = parameter;

                                    builder.Append(newParameterName);
                                }
                            }
                        }
                    }

                    builder.Append(")");
                }

                return (builder.ToString(), parameters);
            }

            public string GraphName { get; }
            public IGremlinQueryProvider Provider { get; }
            public IImmutableList<GremlinStep> Steps { get; }
            public IImmutableDictionary<MemberInfo, string> MemberInfoMappings { get; }
        }

        private sealed class GremlinQueryImpl<T> : GremlinQueryImpl, IGremlinQuery<T>
{'fraction_non_alphanumeric': 0.06496318752706799, 'fraction_numerical': 0.00028872527789807997, 'mean_word_length': 1.1356350184956843, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5191308', 'n_tokens_mistral': 1493, 'n_tokens_neox': 1373, 'n_words': 316}