in src/JetBrains.Space.Generator/CodeGeneration/CSharp/Generators/CSharpApiModelResourceGenerator.cs [383:498]
private string GenerateEnumerableMethodForBatchApiEndpoint(ApiEndpoint apiEndpoint, string baseEndpointPath)
{
var requestBodyObject = apiEndpoint.RequestBody as ApiFieldType.Object;
var indent = new Indent();
var builder = new CSharpBuilder();
var endpointPath = (baseEndpointPath + "/" + apiEndpoint.Path.Segments.ToPath()).TrimEnd('/');
var methodNameForEndpoint = apiEndpoint.ToCSharpMethodName();
var batchDataType = ((ApiFieldType.Object)apiEndpoint.ResponseBody!).GetBatchDataType()!;
var hasSkipParameter = apiEndpoint.Parameters.Any(it => it.Field.Name == "$skip") ||
requestBodyObject?.Fields.Any(it => it.Name == "skip") == true;
var hasBatchInfoParameter = requestBodyObject?.Fields.Any(it => it.Name == "batchInfo") == true;
if (apiEndpoint.ResponseBody != null && (hasSkipParameter || hasBatchInfoParameter))
{
var methodParametersBuilder = new MethodParametersBuilder(_codeGenerationContext)
.WithParametersForApiParameters(apiEndpoint.Parameters);
if (apiEndpoint.RequestBody != null)
{
if (requestBodyObject != null && FeatureFlags.DoNotExposeRequestObjects)
{
methodParametersBuilder = methodParametersBuilder
.WithParametersForApiFields(requestBodyObject.Fields);
}
else
{
methodParametersBuilder = methodParametersBuilder
.WithParameter(
apiEndpoint.ToCSharpRequestBodyClassName(endpointPath)!,
"data");
}
}
var partialType = "Partial<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">";
var funcType = $"Func<{partialType}, {partialType}>?";
methodParametersBuilder = methodParametersBuilder
.WithParameter(
funcType,
"partial",
CSharpExpression.NullLiteral);
methodParametersBuilder = methodParametersBuilder
.WithParameter(CSharpType.CancellationToken.Value,
"cancellationToken",
CSharpExpression.DefaultLiteral);
builder.Append(
indent.Wrap(GenerateMethodDocumentationForEndpoint(apiEndpoint, methodParametersBuilder)));
builder.Append($"{indent}public IAsyncEnumerable<");
builder.Append(batchDataType.ElementType.ToCSharpType(_codeGenerationContext));
builder.Append(">");
builder.Append($" {methodNameForEndpoint}AsyncEnumerable(");
builder.Append(methodParametersBuilder.BuildMethodParametersList());
builder.AppendLine(")");
indent.Increment();
if (hasSkipParameter)
{
// Batch enumerator v1 - Pass a "skip" parameter
builder.Append($"{indent}=> BatchEnumerator.AllItems((batchSkip, batchCancellationToken) => ");
builder.Append($"{methodNameForEndpoint}Async(");
var partialTypeForBatch = "Partial<Batch<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">>";
builder.Append(
methodParametersBuilder
.WithDefaultValueForAllParameters(null)
.WithDefaultValueForParameter("skip", "batchSkip")
.WithDefaultValueForParameter("partial", $"builder => {partialTypeForBatch}.Default().WithNext().WithTotalCount().WithData(partial != null ? partial : _ => {partialType}.Default())")
.WithDefaultValueForParameter(CSharpType.CancellationToken.Value, "batchCancellationToken")
.BuildMethodCallParameters());
builder.Append("), skip, cancellationToken);");
}
else if (hasBatchInfoParameter)
{
// Batch enumerator v2 - Pass a "batchInfo" parameter
builder.Append($"{indent}=> BatchEnumerator.AllItems((batchSkip, batchCancellationToken) => ");
builder.Append($"{methodNameForEndpoint}Async(");
var partialTypeForBatch = "Partial<Batch<" + batchDataType.GetBatchElementTypeOrType().ToCSharpType(_codeGenerationContext) + ">>";
builder.Append(
methodParametersBuilder
.WithDefaultValueForAllParameters(null)
.WithDefaultValueForParameter("batchInfo", "new BatchInfo(batchSize: batchInfo?.BatchSize ?? 100, offset: batchInfo?.Offset)")
.WithDefaultValueForParameter("partial", $"builder => {partialTypeForBatch}.Default().WithNext().WithTotalCount().WithData(partial != null ? partial : _ => {partialType}.Default())")
.WithDefaultValueForParameter(CSharpType.CancellationToken.Value, "batchCancellationToken")
.BuildMethodCallParameters());
builder.Append("), batchInfo?.Offset, cancellationToken);");
}
else
{
builder.Append($"{indent}=> throw new Exception(\"No 'skip' or 'batchInfo' parameter exists for this method.\");");
}
indent.Decrement();
}
else if (!hasSkipParameter && !hasBatchInfoParameter)
{
builder.AppendLine($"{indent}#warning UNSUPPORTED CASE - NO SKIP OR BATCHINFO PARAMETER - " + apiEndpoint.ToCSharpMethodName() + " - " + apiEndpoint.Method.ToHttpMethod() + " " + endpointPath);
}
else
{
builder.AppendLine($"{indent}#warning UNSUPPORTED CASE - " + apiEndpoint.ToCSharpMethodName() + " - " + apiEndpoint.Method.ToHttpMethod() + " " + endpointPath);
}
return builder.ToString();
}