diff --git a/lib/modules/manager/gradle/parser.ts b/lib/modules/manager/gradle/parser.ts
index 02a788145d25c7bbcd507b942687a46dcee0bd13..edc0040911874140f10ea2900d828fb1938d06cc 100644
--- a/lib/modules/manager/gradle/parser.ts
+++ b/lib/modules/manager/gradle/parser.ts
@@ -56,6 +56,7 @@ export function parseGradle(
     registryUrls: [],
 
     varTokens: [],
+    tmpNestingDepth: [],
     tmpTokenStore: {},
     tokenMap: {},
   });
diff --git a/lib/modules/manager/gradle/parser/assignments.ts b/lib/modules/manager/gradle/parser/assignments.ts
index e8af871ffa3674d5c19017bbcf82f1184320c1cb..9b5ccbd49ba4615373e32957ee11f1a068b3a03f 100644
--- a/lib/modules/manager/gradle/parser/assignments.ts
+++ b/lib/modules/manager/gradle/parser/assignments.ts
@@ -4,9 +4,12 @@ import type { Ctx } from '../types';
 import {
   cleanupTempVars,
   coalesceVariable,
+  increaseNestingDepth,
+  prependNestingDepth,
   qStringValue,
   qTemplateString,
   qVariableAssignmentIdentifier,
+  reduceNestingDepth,
   storeInTokenMap,
   storeVarToken,
 } from './common';
@@ -65,40 +68,27 @@ const qKotlinSingleExtraVarAssignment = q
 // foo: "1.2.3"
 const qGroovySingleMapOfVarAssignment = q
   .sym(storeVarToken)
-  .handler((ctx) => {
-    ctx.tmpTokenStore.backupVarTokens = ctx.varTokens;
-    return ctx;
-  })
+  .handler(prependNestingDepth)
   .handler(coalesceVariable)
   .handler((ctx) => storeInTokenMap(ctx, 'keyToken'))
   .op(':')
   .join(qTemplateString)
   .handler((ctx) => storeInTokenMap(ctx, 'valToken'))
-  .handler(handleAssignment)
-  .handler((ctx) => {
-    ctx.varTokens = ctx.tmpTokenStore.backupVarTokens!;
-    ctx.varTokens.pop();
-    return ctx;
-  });
+  .handler(handleAssignment);
 
 const qGroovyMapOfExpr = (
   search: q.QueryBuilder<Ctx, parser.Node>
 ): q.QueryBuilder<Ctx, parser.Node> =>
   q.alt(
-    q
-      .sym(storeVarToken)
-      .op(':')
-      .tree({
-        type: 'wrapped-tree',
-        maxDepth: 1,
-        startsWith: '[',
-        endsWith: ']',
-        search,
-        postHandler: (ctx: Ctx) => {
-          ctx.varTokens.pop();
-          return ctx;
-        },
-      }),
+    q.sym(storeVarToken).op(':').tree({
+      type: 'wrapped-tree',
+      maxDepth: 1,
+      startsWith: '[',
+      endsWith: ']',
+      preHandler: increaseNestingDepth,
+      search,
+      postHandler: reduceNestingDepth,
+    }),
     qGroovySingleMapOfVarAssignment
   );
 
@@ -110,46 +100,35 @@ const qGroovyMultiVarAssignment = qVariableAssignmentIdentifier
     maxDepth: 1,
     startsWith: '[',
     endsWith: ']',
+    preHandler: increaseNestingDepth,
     search: qGroovyMapOfExpr(qGroovyMapOfExpr(qGroovySingleMapOfVarAssignment)),
+    postHandler: reduceNestingDepth,
   })
   .handler(cleanupTempVars);
 
 // "foo1" to "bar1"
 const qKotlinSingleMapOfVarAssignment = qStringValue
   .sym('to')
-  .handler((ctx) => {
-    ctx.tmpTokenStore.backupVarTokens = ctx.varTokens;
-    return ctx;
-  })
+  .handler(prependNestingDepth)
   .handler(coalesceVariable)
   .handler((ctx) => storeInTokenMap(ctx, 'keyToken'))
   .join(qTemplateString)
   .handler((ctx) => storeInTokenMap(ctx, 'valToken'))
-  .handler(handleAssignment)
-  .handler((ctx) => {
-    ctx.varTokens = ctx.tmpTokenStore.backupVarTokens!;
-    ctx.varTokens.pop();
-    return ctx;
-  });
+  .handler(handleAssignment);
 
 const qKotlinMapOfExpr = (
   search: q.QueryBuilder<Ctx, parser.Node>
 ): q.QueryBuilder<Ctx, parser.Node> =>
   q.alt(
-    qStringValue
-      .sym('to')
-      .sym('mapOf')
-      .tree({
-        type: 'wrapped-tree',
-        maxDepth: 1,
-        startsWith: '(',
-        endsWith: ')',
-        search,
-        postHandler: (ctx: Ctx) => {
-          ctx.varTokens.pop();
-          return ctx;
-        },
-      }),
+    qStringValue.sym('to').sym('mapOf').tree({
+      type: 'wrapped-tree',
+      maxDepth: 1,
+      startsWith: '(',
+      endsWith: ')',
+      preHandler: increaseNestingDepth,
+      search,
+      postHandler: reduceNestingDepth,
+    }),
     qKotlinSingleMapOfVarAssignment
   );
 
@@ -162,7 +141,9 @@ const qKotlinMultiMapOfVarAssignment = qVariableAssignmentIdentifier
     maxDepth: 1,
     startsWith: '(',
     endsWith: ')',
+    preHandler: increaseNestingDepth,
     search: qKotlinMapOfExpr(qKotlinMapOfExpr(qKotlinSingleMapOfVarAssignment)),
+    postHandler: reduceNestingDepth,
   })
   .handler(cleanupTempVars);
 
diff --git a/lib/modules/manager/gradle/parser/common.spec.ts b/lib/modules/manager/gradle/parser/common.spec.ts
index 7b8779b0a17f791a97ba0f390a321870dac56601..c2742363c049a73da6f16d175cccb645750cbbf3 100644
--- a/lib/modules/manager/gradle/parser/common.spec.ts
+++ b/lib/modules/manager/gradle/parser/common.spec.ts
@@ -4,8 +4,11 @@ import type { Ctx, PackageVariables } from '../types';
 import {
   cleanupTempVars,
   coalesceVariable,
+  increaseNestingDepth,
   interpolateString,
   loadFromTokenMap,
+  prependNestingDepth,
+  reduceNestingDepth,
   storeInTokenMap,
   storeVarToken,
   stripReservedPrefixFromKeyTokens,
@@ -13,7 +16,7 @@ import {
 
 describe('modules/manager/gradle/parser/common', () => {
   let ctx: Ctx;
-  const token = partial<lexer.Token>({});
+  const token = partial<lexer.Token>({ value: 'test' });
 
   beforeEach(() => {
     ctx = {
@@ -26,6 +29,7 @@ describe('modules/manager/gradle/parser/common', () => {
       registryUrls: [],
 
       varTokens: [],
+      tmpNestingDepth: [],
       tmpTokenStore: {},
       tokenMap: {},
     };
@@ -36,6 +40,33 @@ describe('modules/manager/gradle/parser/common', () => {
     expect(ctx.varTokens).toStrictEqual([token]);
   });
 
+  it('increaseNestingDepth', () => {
+    ctx.tmpNestingDepth = ctx.varTokens = [token];
+    increaseNestingDepth(ctx);
+    expect(ctx).toMatchObject({
+      tmpNestingDepth: [token, token],
+      varTokens: [],
+    });
+  });
+
+  it('reduceNestingDepth', () => {
+    ctx.tmpNestingDepth = [token, token];
+    reduceNestingDepth(ctx);
+    expect(ctx.tmpNestingDepth).toHaveLength(1);
+  });
+
+  it('prependNestingDepth', () => {
+    ctx.tmpNestingDepth = ctx.varTokens = [token];
+    prependNestingDepth(ctx);
+    expect(ctx.varTokens).toStrictEqual([token, token]);
+
+    coalesceVariable(ctx);
+    expect(ctx).toMatchObject({
+      tmpNestingDepth: [{ value: 'test' }],
+      varTokens: [{ value: 'test.test' }],
+    });
+  });
+
   it('storeInTokenMap', () => {
     ctx.varTokens = [token];
     storeInTokenMap(ctx, 'foo');
diff --git a/lib/modules/manager/gradle/parser/common.ts b/lib/modules/manager/gradle/parser/common.ts
index 6f73dae18b41785bc83cafe83a395f7d428d18f0..69fddc91470dd81d370e81a4efe4cbc7424038ab 100644
--- a/lib/modules/manager/gradle/parser/common.ts
+++ b/lib/modules/manager/gradle/parser/common.ts
@@ -1,4 +1,5 @@
 import { lexer, parser, query as q } from 'good-enough-parser';
+import { clone } from '../../../../util/clone';
 import { regEx } from '../../../../util/regex';
 import type { Ctx, NonEmptyArray, PackageVariables } from '../types';
 
@@ -39,6 +40,22 @@ export function storeVarToken(ctx: Ctx, node: lexer.Token): Ctx {
   return ctx;
 }
 
+export function increaseNestingDepth(ctx: Ctx): Ctx {
+  ctx.tmpNestingDepth.push(...ctx.varTokens);
+  ctx.varTokens = [];
+  return ctx;
+}
+
+export function reduceNestingDepth(ctx: Ctx): Ctx {
+  ctx.tmpNestingDepth.pop();
+  return ctx;
+}
+
+export function prependNestingDepth(ctx: Ctx): Ctx {
+  ctx.varTokens = [...clone(ctx.tmpNestingDepth), ...ctx.varTokens];
+  return ctx;
+}
+
 export function storeInTokenMap(ctx: Ctx, tokenMapKey: string): Ctx {
   ctx.tokenMap[tokenMapKey] = ctx.varTokens;
   ctx.varTokens = [];
diff --git a/lib/modules/manager/gradle/types.ts b/lib/modules/manager/gradle/types.ts
index a4646dbef8ab8619c1c57b93fee1ee330493ceff..7222c36345aa7111d232dcd6d34665ff9b9bb92f 100644
--- a/lib/modules/manager/gradle/types.ts
+++ b/lib/modules/manager/gradle/types.ts
@@ -82,6 +82,7 @@ export interface Ctx {
   registryUrls: PackageRegistry[];
 
   varTokens: lexer.Token[];
+  tmpNestingDepth: lexer.Token[];
   tmpTokenStore: Record<string, lexer.Token[]>;
   tokenMap: Record<string, lexer.Token[]>;
 }