Browse code

vendor: update buildkit to v0.25.0-rc1

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>

Tonis Tiigi authored on 2025/09/24 05:33:46
Showing 76 changed files
... ...
@@ -55,7 +55,7 @@ require (
55 55
 	github.com/miekg/dns v1.1.66
56 56
 	github.com/mistifyio/go-zfs/v3 v3.0.1
57 57
 	github.com/mitchellh/copystructure v1.2.0
58
-	github.com/moby/buildkit v0.24.0
58
+	github.com/moby/buildkit v0.25.0-rc1
59 59
 	github.com/moby/docker-image-spec v1.3.1
60 60
 	github.com/moby/go-archive v0.1.0
61 61
 	github.com/moby/ipvs v1.1.0
... ...
@@ -110,7 +110,7 @@ require (
110 110
 	golang.org/x/time v0.11.0
111 111
 	google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a
112 112
 	google.golang.org/grpc v1.72.2
113
-	google.golang.org/protobuf v1.36.6
113
+	google.golang.org/protobuf v1.36.9
114 114
 	gotest.tools/v3 v3.5.2
115 115
 	pgregory.net/rapid v1.2.0
116 116
 	resenje.org/singleflight v0.4.3
... ...
@@ -173,8 +173,8 @@ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi
173 173
 github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
174 174
 github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
175 175
 github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
176
-github.com/docker/cli v28.3.3+incompatible h1:fp9ZHAr1WWPGdIWBM1b3zLtgCF+83gRdVMTJsUeiyAo=
177
-github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
176
+github.com/docker/cli v28.4.0+incompatible h1:RBcf3Kjw2pMtwui5V0DIMdyeab8glEw5QY0UUU4C9kY=
177
+github.com/docker/cli v28.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
178 178
 github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
179 179
 github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
180 180
 github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
... ...
@@ -396,8 +396,8 @@ github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:F
396 396
 github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
397 397
 github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
398 398
 github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
399
-github.com/moby/buildkit v0.24.0 h1:qYfTl7W1SIJzWDIDCcPT8FboHIZCYfi++wvySi3eyFE=
400
-github.com/moby/buildkit v0.24.0/go.mod h1:4qovICAdR2H4C7+EGMRva5zgHW1gyhT4/flHI7F5F9k=
399
+github.com/moby/buildkit v0.25.0-rc1 h1:BX93yFRfF1LzD12wCOhjncbpL3RvkPa1+fF7xmsdr28=
400
+github.com/moby/buildkit v0.25.0-rc1/go.mod h1:phM8sdqnvgK2y1dPDnbwI6veUCXHOZ6KFSl6E164tkc=
401 401
 github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
402 402
 github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
403 403
 github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
... ...
@@ -808,8 +808,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
808 808
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
809 809
 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
810 810
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
811
-google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
812
-google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
811
+google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
812
+google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
813 813
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
814 814
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
815 815
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/api/services/control/control.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/api/types/worker.proto
6 6
 
... ...
@@ -92,6 +92,7 @@ type includedPath struct {
92 92
 	included         bool
93 93
 	includeMatchInfo patternmatcher.MatchInfo
94 94
 	excludeMatchInfo patternmatcher.MatchInfo
95
+	followLinks      bool
95 96
 }
96 97
 
97 98
 type cacheManager struct {
... ...
@@ -431,17 +432,16 @@ func (cc *cacheContext) Checksum(ctx context.Context, mountable cache.Mountable,
431 431
 		return "", err
432 432
 	}
433 433
 
434
-	if opts.FollowLinks {
435
-		for i, w := range includedPaths {
436
-			if w.record.Type == CacheRecordTypeSymlink {
437
-				dgst, err := cc.lazyChecksum(ctx, m, w.path, opts.FollowLinks)
438
-				if err != nil {
439
-					return "", err
440
-				}
441
-				includedPaths[i].record = &CacheRecord{Digest: string(dgst)}
434
+	for i, w := range includedPaths {
435
+		if w.followLinks && w.record.Type == CacheRecordTypeSymlink {
436
+			dgst, err := cc.lazyChecksum(ctx, m, w.path, opts.FollowLinks)
437
+			if err != nil {
438
+				return "", err
442 439
 			}
440
+			includedPaths[i].record = &CacheRecord{Digest: string(dgst)}
443 441
 		}
444 442
 	}
443
+
445 444
 	if len(includedPaths) == 0 {
446 445
 		return digest.FromBytes([]byte{}), nil
447 446
 	}
... ...
@@ -597,6 +597,10 @@ func (cc *cacheContext) includedPaths(ctx context.Context, m *mount, p string, o
597 597
 		}
598 598
 
599 599
 		maybeIncludedPath := &includedPath{path: fn}
600
+		if parentDir == nil && opts.FollowLinks {
601
+			maybeIncludedPath.followLinks = true
602
+		}
603
+
600 604
 		var shouldInclude bool
601 605
 		if opts.Wildcard {
602 606
 			if p != "" && (lastMatchedDir == "" || !strings.HasPrefix(fn, lastMatchedDir+"/")) {
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/cache/contenthash/checksum.proto
6 6
 
... ...
@@ -5,7 +5,6 @@ import (
5 5
 	"slices"
6 6
 	"time"
7 7
 
8
-	"github.com/moby/buildkit/identity"
9 8
 	"github.com/moby/buildkit/session"
10 9
 	"github.com/moby/buildkit/solver"
11 10
 	"github.com/moby/buildkit/util/compression"
... ...
@@ -21,8 +20,11 @@ func NewCacheKeyStorage(cc *CacheChains, w worker.Worker) (solver.CacheKeyStorag
21 21
 		byResult: map[string]map[string]struct{}{},
22 22
 	}
23 23
 
24
-	for _, it := range cc.items {
25
-		if _, err := addItemToStorage(storage, it); err != nil {
24
+	cc.computeIDs()
25
+
26
+	for it := range cc.leaves() {
27
+		visited := make(map[*item]*itemWithOutgoingLinks)
28
+		if _, err := addItemToStorage(storage, it, visited); err != nil {
26 29
 			return nil, nil, err
27 30
 		}
28 31
 	}
... ...
@@ -37,7 +39,12 @@ func NewCacheKeyStorage(cc *CacheChains, w worker.Worker) (solver.CacheKeyStorag
37 37
 	return storage, results, nil
38 38
 }
39 39
 
40
-func addItemToStorage(k *cacheKeyStorage, it *item) (*itemWithOutgoingLinks, error) {
40
+func addItemToStorage(k *cacheKeyStorage, it *item, visited map[*item]*itemWithOutgoingLinks) (*itemWithOutgoingLinks, error) {
41
+	if v, ok := visited[it]; ok {
42
+		return v, nil
43
+	}
44
+	visited[it] = nil
45
+
41 46
 	if id, ok := k.byItem[it]; ok {
42 47
 		if id == "" {
43 48
 			return nil, errors.Errorf("invalid loop")
... ...
@@ -45,21 +52,18 @@ func addItemToStorage(k *cacheKeyStorage, it *item) (*itemWithOutgoingLinks, err
45 45
 		return k.byID[id], nil
46 46
 	}
47 47
 
48
-	var id string
49
-	if len(it.links) == 0 {
50
-		id = it.dgst.String()
51
-	} else {
52
-		id = identity.NewID()
53
-	}
54
-
48
+	id := it.id
55 49
 	k.byItem[it] = ""
56 50
 
57
-	for i, m := range it.links {
51
+	for i, m := range it.parents {
58 52
 		for l := range m {
59
-			src, err := addItemToStorage(k, l.src)
53
+			src, err := addItemToStorage(k, l.src, visited)
60 54
 			if err != nil {
61 55
 				return nil, err
62 56
 			}
57
+			if src == nil {
58
+				continue
59
+			}
63 60
 			cl := nlink{
64 61
 				input:    i,
65 62
 				dgst:     it.dgst,
... ...
@@ -78,8 +82,13 @@ func addItemToStorage(k *cacheKeyStorage, it *item) (*itemWithOutgoingLinks, err
78 78
 
79 79
 	k.byID[id] = itl
80 80
 
81
-	if res := it.result; res != nil {
82
-		resultID := remoteID(res)
81
+	seen := map[string]struct{}{}
82
+	for _, res := range it.results {
83
+		resultID := remoteID(res.Result)
84
+		if _, ok := seen[resultID]; ok {
85
+			continue
86
+		}
87
+		seen[resultID] = struct{}{}
83 88
 		ids, ok := k.byResult[resultID]
84 89
 		if !ok {
85 90
 			ids = map[string]struct{}{}
... ...
@@ -87,6 +96,7 @@ func addItemToStorage(k *cacheKeyStorage, it *item) (*itemWithOutgoingLinks, err
87 87
 		}
88 88
 		ids[id] = struct{}{}
89 89
 	}
90
+	visited[it] = itl
90 91
 	return itl, nil
91 92
 }
92 93
 
... ...
@@ -120,21 +130,32 @@ func (cs *cacheKeyStorage) WalkResults(id string, fn func(solver.CacheResult) er
120 120
 	if !ok {
121 121
 		return nil
122 122
 	}
123
-	if res := it.result; res != nil {
124
-		return fn(solver.CacheResult{ID: remoteID(res), CreatedAt: it.resultTime})
123
+	seen := map[string]struct{}{}
124
+	for _, res := range it.results {
125
+		id := remoteID(res.Result)
126
+		if _, ok := seen[id]; ok {
127
+			continue
128
+		}
129
+		if err := fn(solver.CacheResult{ID: id, CreatedAt: res.CreatedAt}); err != nil {
130
+			return err
131
+		}
132
+		seen[id] = struct{}{}
125 133
 	}
126 134
 	return nil
127 135
 }
128 136
 
129 137
 func (cs *cacheKeyStorage) Load(id string, resultID string) (solver.CacheResult, error) {
130
-	it, ok := cs.byID[id]
131
-	if !ok {
132
-		return solver.CacheResult{}, nil
133
-	}
134
-	if res := it.result; res != nil {
135
-		return solver.CacheResult{ID: remoteID(res), CreatedAt: it.resultTime}, nil
138
+	var res solver.CacheResult
139
+	if err := cs.WalkResults(id, func(r solver.CacheResult) error {
140
+		if r.ID == resultID {
141
+			res = r
142
+			return nil
143
+		}
144
+		return nil
145
+	}); err != nil {
146
+		return solver.CacheResult{}, errors.Wrapf(err, "failed to load cache result for %s", id)
136 147
 	}
137
-	return solver.CacheResult{}, nil
148
+	return res, nil
138 149
 }
139 150
 
140 151
 func (cs *cacheKeyStorage) AddResult(id string, res solver.CacheResult) error {
... ...
@@ -250,28 +271,35 @@ func (cs *cacheResultStorage) LoadWithParents(ctx context.Context, res solver.Ca
250 250
 
251 251
 	for id := range ids {
252 252
 		v, ok := cs.byID[id]
253
-		if ok && v.result != nil {
254
-			if err := v.walkAllResults(func(i *item) error {
255
-				if i.result == nil {
256
-					return nil
257
-				}
258
-				id, ok := cs.byItem[i]
259
-				if !ok {
260
-					return nil
261
-				}
262
-				if isSubRemote(*i.result, *v.result) {
263
-					ref, err := cs.w.FromRemote(ctx, i.result)
264
-					if err != nil {
265
-						return err
253
+		if ok {
254
+			if _, ok := visited[v.item]; ok {
255
+				continue
256
+			}
257
+			for _, result := range v.results {
258
+				resultID := remoteID(result.Result)
259
+				if resultID == res.ID {
260
+					if err := v.walkAllResults(func(i *item) error {
261
+						for _, subRes := range i.results {
262
+							id, ok := cs.byItem[i]
263
+							if !ok {
264
+								return nil
265
+							}
266
+							if isSubRemote(*subRes.Result, *result.Result) {
267
+								ref, err := cs.w.FromRemote(ctx, subRes.Result)
268
+								if err != nil {
269
+									return err
270
+								}
271
+								m[id] = worker.NewWorkerRefResult(ref, cs.w)
272
+							}
273
+						}
274
+						return nil
275
+					}, visited); err != nil {
276
+						for _, v := range m {
277
+							v.Release(context.TODO())
278
+						}
279
+						return nil, err
266 280
 					}
267
-					m[id] = worker.NewWorkerRefResult(ref, cs.w)
268 281
 				}
269
-				return nil
270
-			}, visited); err != nil {
271
-				for _, v := range m {
272
-					v.Release(context.TODO())
273
-				}
274
-				return nil, err
275 282
 			}
276 283
 		}
277 284
 	}
... ...
@@ -281,34 +309,43 @@ func (cs *cacheResultStorage) LoadWithParents(ctx context.Context, res solver.Ca
281 281
 
282 282
 func (cs *cacheResultStorage) Load(ctx context.Context, res solver.CacheResult) (solver.Result, error) {
283 283
 	item := cs.byResultID(res.ID)
284
-	if item == nil || item.result == nil {
285
-		return nil, errors.WithStack(solver.ErrNotFound)
286
-	}
287
-
288
-	ref, err := cs.w.FromRemote(ctx, item.result)
289
-	if err != nil {
290
-		return nil, errors.Wrap(err, "failed to load result from remote")
284
+	for _, r := range item.results {
285
+		resultID := remoteID(r.Result)
286
+		if resultID != res.ID {
287
+			continue
288
+		}
289
+		ref, err := cs.w.FromRemote(ctx, r.Result)
290
+		if err != nil {
291
+			return nil, errors.Wrap(err, "failed to load result from remote")
292
+		}
293
+		return worker.NewWorkerRefResult(ref, cs.w), nil
291 294
 	}
292
-	return worker.NewWorkerRefResult(ref, cs.w), nil
295
+	return nil, errors.WithStack(solver.ErrNotFound)
293 296
 }
294 297
 
295 298
 func (cs *cacheResultStorage) LoadRemotes(ctx context.Context, res solver.CacheResult, compressionopts *compression.Config, _ session.Group) ([]*solver.Remote, error) {
296
-	if r := cs.byResultID(res.ID); r != nil && r.result != nil {
297
-		if compressionopts == nil {
298
-			return []*solver.Remote{r.result}, nil
299
-		}
300
-		// Any of blobs in the remote must meet the specified compression option.
301
-		match := false
302
-		for _, desc := range r.result.Descriptors {
303
-			m := compression.IsMediaType(compressionopts.Type, desc.MediaType)
304
-			match = match || m
305
-			if compressionopts.Force && !m {
306
-				match = false
307
-				break
299
+	if it := cs.byResultID(res.ID); it != nil {
300
+		for _, r := range it.results {
301
+			if compressionopts == nil {
302
+				resultID := remoteID(r.Result)
303
+				if resultID != res.ID {
304
+					continue
305
+				}
306
+				return []*solver.Remote{r.Result}, nil
307
+			}
308
+			// Any of blobs in the remote must meet the specified compression option.
309
+			match := false
310
+			for _, desc := range r.Result.Descriptors {
311
+				m := compression.IsMediaType(compressionopts.Type, desc.MediaType)
312
+				match = match || m
313
+				if compressionopts.Force && !m {
314
+					match = false
315
+					break
316
+				}
317
+			}
318
+			if match {
319
+				return []*solver.Remote{r.Result}, nil
308 320
 			}
309
-		}
310
-		if match {
311
-			return []*solver.Remote{r.result}, nil
312 321
 		}
313 322
 		return nil, nil // return nil as it's best effort.
314 323
 	}
... ...
@@ -2,10 +2,13 @@ package cacheimport
2 2
 
3 3
 import (
4 4
 	"context"
5
+	"encoding/binary"
6
+	"maps"
7
+	"slices"
5 8
 	"strings"
6
-	"sync"
7
-	"time"
9
+	"unique"
8 10
 
11
+	"github.com/cespare/xxhash/v2"
9 12
 	"github.com/containerd/containerd/v2/core/content"
10 13
 	"github.com/moby/buildkit/session"
11 14
 	"github.com/moby/buildkit/solver"
... ...
@@ -15,72 +18,187 @@ import (
15 15
 )
16 16
 
17 17
 func NewCacheChains() *CacheChains {
18
-	return &CacheChains{visited: map[any]struct{}{}}
18
+	return &CacheChains{roots: map[digest.Digest]*item{}}
19 19
 }
20 20
 
21 21
 type CacheChains struct {
22
-	items   []*item
23
-	visited map[any]struct{}
22
+	roots map[digest.Digest]*item
24 23
 }
25 24
 
26 25
 var _ solver.CacheExporterTarget = &CacheChains{}
27 26
 
28
-func (c *CacheChains) Add(dgst digest.Digest) solver.CacheExporterRecord {
29
-	if strings.HasPrefix(dgst.String(), "random:") {
30
-		// random digests will be different *every* run - so we shouldn't cache
31
-		// it, since there's a zero chance this random digest collides again
32
-		return &nopRecord{}
27
+func (c *CacheChains) computeIDs() {
28
+	for it := range c.leaves() {
29
+		it.computeID()
33 30
 	}
34
-
35
-	it := &item{dgst: dgst, backlinks: map[*item]struct{}{}}
36
-	c.items = append(c.items, it)
37
-	return it
38 31
 }
39 32
 
40
-func (c *CacheChains) Visit(target any) {
41
-	c.visited[target] = struct{}{}
33
+func (c *CacheChains) leaves() map[*item]struct{} {
34
+	leafs := map[*item]struct{}{}
35
+	visited := map[*item]struct{}{}
36
+	for _, it := range c.roots {
37
+		it.walkChildren(func(i *item) error {
38
+			if len(i.children) == 0 {
39
+				leafs[i] = struct{}{}
40
+			}
41
+			return nil
42
+		}, visited)
43
+	}
44
+	return leafs
42 45
 }
43 46
 
44
-func (c *CacheChains) Visited(target any) bool {
45
-	_, ok := c.visited[target]
46
-	return ok
47
-}
47
+func (c *CacheChains) Add(dgst digest.Digest, deps [][]solver.CacheLink, results []solver.CacheExportResult) (solver.CacheExporterRecord, bool, error) {
48
+	if strings.HasPrefix(dgst.String(), "random:") {
49
+		return nil, false, nil
50
+	}
51
+	r := &item{
52
+		dgst:    dgst,
53
+		results: results,
54
+		cc:      c,
55
+	}
48 56
 
49
-func (c *CacheChains) normalize(ctx context.Context) error {
50
-	st := &normalizeState{
51
-		added: map[*item]*item{},
52
-		links: map[*item]map[nlink]map[digest.Digest]struct{}{},
53
-		byKey: map[digest.Digest]*item{},
57
+	if len(deps) == 0 {
58
+		if prev, ok := c.roots[dgst]; ok {
59
+			r = prev
60
+		}
61
+		for _, rr := range results {
62
+			r.addResult(rr)
63
+		}
64
+		c.roots[dgst] = r
65
+		return r, true, nil
54 66
 	}
55 67
 
56
-	validated := make([]*item, 0, len(c.items))
57
-	for _, it := range c.items {
58
-		it.backlinksMu.Lock()
59
-		it.validate()
60
-		it.backlinksMu.Unlock()
68
+	matchDeps := make([]func() map[*item]struct{}, len(deps))
69
+	for i, dd := range deps {
70
+		if len(dd) == 0 {
71
+			return nil, false, errors.Errorf("empty dependency for %s", dgst)
72
+		}
73
+		type itemWithSelector struct {
74
+			Src      *item
75
+			Selector string
76
+		}
77
+		items := make([]itemWithSelector, len(dd))
78
+		for ii, d := range dd {
79
+			it, ok := d.Src.(*item)
80
+			if !ok {
81
+				return nil, false, errors.Errorf("invalid dependency type %T for %s", d.Src, dgst)
82
+			}
83
+			if it.cc != c {
84
+				return nil, false, errors.Errorf("dependency %s is not part of the same cache chain", it.dgst)
85
+			}
86
+			items[ii] = itemWithSelector{
87
+				Src:      it,
88
+				Selector: d.Selector,
89
+			}
90
+		}
91
+		matchDeps[i] = func() map[*item]struct{} {
92
+			candidates := map[*item]struct{}{}
93
+			for _, it := range items {
94
+				maps.Copy(candidates, it.Src.children[unique.Make(linkv2{
95
+					selector: it.Selector,
96
+					index:    i,
97
+					digest:   dgst,
98
+				})])
99
+			}
100
+			return candidates
101
+		}
61 102
 	}
62
-	for _, it := range c.items {
63
-		if !it.invalid {
64
-			validated = append(validated, it)
103
+	items := IntersectAll(matchDeps)
104
+
105
+	if len(items) > 1 {
106
+		var main *item
107
+		for it := range items {
108
+			main = it
109
+			break
65 110
 		}
111
+		for it := range items {
112
+			if it == main {
113
+				continue
114
+			}
115
+			for l, m := range it.children {
116
+				if main.children == nil {
117
+					main.children = map[unique.Handle[linkv2]]map[*item]struct{}{}
118
+				}
119
+				if _, ok := main.children[l]; !ok {
120
+					main.children[l] = map[*item]struct{}{}
121
+				}
122
+				for ch := range m {
123
+					main.children[l][ch] = struct{}{}
124
+					for i, links := range ch.parents {
125
+						newlinks := map[link]struct{}{}
126
+						for l := range links {
127
+							if l.src == it {
128
+								l.src = main
129
+							}
130
+							newlinks[l] = struct{}{}
131
+						}
132
+						ch.parents[i] = newlinks
133
+					}
134
+				}
135
+			}
136
+			for _, rr := range it.results {
137
+				main.addResult(rr)
138
+			}
139
+		}
140
+		items = map[*item]struct{}{main: {}}
66 141
 	}
67
-	c.items = validated
68 142
 
69
-	for _, it := range c.items {
70
-		_, err := normalizeItem(it, st)
71
-		if err != nil {
72
-			return err
143
+	for it := range items {
144
+		r = it
145
+		for _, rr := range results {
146
+			r.addResult(rr)
147
+		}
148
+
149
+		// make sure that none of the deps are children of r
150
+		allChildren := map[*item]struct{}{}
151
+		if err := r.walkChildren(func(i *item) error {
152
+			allChildren[i] = struct{}{}
153
+			return nil
154
+		}, map[*item]struct{}{}); err != nil {
155
+			return nil, false, errors.Wrapf(err, "failed to walk children of %s", dgst)
156
+		}
157
+		for i, dd := range deps {
158
+			for j, d := range dd {
159
+				if _, ok := allChildren[d.Src.(*item)]; ok {
160
+					deps[i][j].Src = nil
161
+				}
162
+			}
163
+		}
164
+		break
165
+	}
166
+	for i, dd := range deps {
167
+		for _, d := range dd {
168
+			if d.Src == nil {
169
+				continue
170
+			}
171
+			d.Src.(*item).addChild(r, i, d.Selector)
73 172
 		}
74 173
 	}
174
+	return r, true, nil
175
+}
176
+
177
+func IntersectAll[T comparable](
178
+	funcs []func() map[T]struct{},
179
+) map[T]struct{} {
180
+	if len(funcs) == 0 {
181
+		return nil
182
+	}
75 183
 
76
-	st.removeLoops(ctx)
184
+	intersection := funcs[0]()
77 185
 
78
-	items := make([]*item, 0, len(st.byKey))
79
-	for _, it := range st.byKey {
80
-		items = append(items, it)
186
+	for _, f := range funcs[1:] {
187
+		next := f()
188
+		for k := range intersection {
189
+			if _, ok := next[k]; !ok {
190
+				delete(intersection, k)
191
+			}
192
+		}
193
+		if len(intersection) == 0 {
194
+			return nil
195
+		}
81 196
 	}
82
-	c.items = items
83
-	return nil
197
+
198
+	return intersection
84 199
 }
85 200
 
86 201
 // Marshal converts the cache chains structure into a cache config and a
... ...
@@ -90,17 +208,13 @@ func (c *CacheChains) normalize(ctx context.Context) error {
90 90
 // consistent digest (since cache configs are typically uploaded and stored in
91 91
 // content-addressable OCI registries).
92 92
 func (c *CacheChains) Marshal(ctx context.Context) (*CacheConfig, DescriptorProvider, error) {
93
-	if err := c.normalize(ctx); err != nil {
94
-		return nil, nil, err
95
-	}
96
-
97 93
 	st := &marshalState{
98 94
 		chainsByID:    map[string]int{},
99 95
 		descriptors:   DescriptorProvider{},
100 96
 		recordsByItem: map[*item]int{},
101 97
 	}
102 98
 
103
-	for _, it := range c.items {
99
+	for it := range c.leaves() {
104 100
 		if err := marshalItem(ctx, it, st); err != nil {
105 101
 			return nil, nil, err
106 102
 		}
... ...
@@ -160,34 +274,33 @@ func (p DescriptorProviderPair) SnapshotLabels(descs []ocispecs.Descriptor, inde
160 160
 	return nil
161 161
 }
162 162
 
163
+type linkv2 struct {
164
+	selector string
165
+	index    int
166
+	digest   digest.Digest
167
+}
168
+
163 169
 // item is an implementation of a record in the cache chain. After validation,
164 170
 // normalization and marshalling into the cache config, the item results form
165 171
 // into the "layers", while the digests and the links form into the "records".
166 172
 type item struct {
173
+	solver.CacheExporterRecordBase
174
+
175
+	id string
176
+
167 177
 	// dgst is the unique identifier for each record.
168 178
 	// This *roughly* corresponds to an edge (vertex cachekey + index) in the
169 179
 	// solver - however, a single vertex can produce multiple unique cache keys
170 180
 	// (e.g. fast/slow), so it's a one-to-many relation.
171 181
 	dgst digest.Digest
172 182
 
173
-	// links are what connect records to each other (with an optional selector),
174
-	// organized by input index (which correspond to vertex inputs).
175
-	// We can have multiple links for each index, since *any* of these could be
176
-	// used to get to this item (e.g. we could retrieve by fast/slow key).
177
-	links []map[link]struct{}
183
+	children map[unique.Handle[linkv2]]map[*item]struct{}
178 184
 
179
-	// backlinks are the inverse of a link - these don't actually get directly
180
-	// exported, but they're internally used to help efficiently navigate the
181
-	// graph.
182
-	backlinks   map[*item]struct{}
183
-	backlinksMu sync.Mutex
185
+	parents []map[link]struct{}
184 186
 
185
-	// result is the result of computing the edge - this is the target of the
186
-	// data we actually want to store in the cache chain.
187
-	result     *solver.Remote
188
-	resultTime time.Time
187
+	results []solver.CacheExportResult
189 188
 
190
-	invalid bool
189
+	cc *CacheChains
191 190
 }
192 191
 
193 192
 // link is a pointer to an item, with an optional selector.
... ...
@@ -196,88 +309,110 @@ type link struct {
196 196
 	selector string
197 197
 }
198 198
 
199
-func (c *item) removeLink(src *item) bool {
200
-	found := false
201
-	for idx := range c.links {
202
-		for l := range c.links[idx] {
203
-			if l.src == src {
204
-				delete(c.links[idx], l)
205
-				found = true
206
-			}
207
-		}
208
-	}
209
-	for idx := range c.links {
210
-		if len(c.links[idx]) == 0 {
211
-			c.links = nil
212
-			break
213
-		}
199
+func (c *item) addChild(src *item, index int, selector string) {
200
+	if c.children == nil {
201
+		c.children = map[unique.Handle[linkv2]]map[*item]struct{}{}
214 202
 	}
215
-	return found
216
-}
217
-
218
-func (c *item) AddResult(_ digest.Digest, _ int, createdAt time.Time, result *solver.Remote) {
219
-	c.resultTime = createdAt
220
-	c.result = result
221
-}
222
-
223
-func (c *item) LinkFrom(rec solver.CacheExporterRecord, index int, selector string) {
224
-	src, ok := rec.(*item)
203
+	h := unique.Make(linkv2{
204
+		selector: selector,
205
+		index:    index,
206
+		digest:   src.dgst,
207
+	})
208
+	m, ok := c.children[h]
225 209
 	if !ok {
210
+		m = map[*item]struct{}{}
211
+		c.children[h] = m
212
+	}
213
+	if _, ok := m[src]; ok {
226 214
 		return
227 215
 	}
216
+	m[src] = struct{}{}
228 217
 
229
-	for index >= len(c.links) {
230
-		c.links = append(c.links, map[link]struct{}{})
218
+	for index >= len(src.parents) {
219
+		src.parents = append(src.parents, map[link]struct{}{})
231 220
 	}
221
+	src.parents[index][link{src: c, selector: selector}] = struct{}{}
222
+}
232 223
 
233
-	c.links[index][link{src: src, selector: selector}] = struct{}{}
234
-	src.backlinksMu.Lock()
235
-	src.backlinks[c] = struct{}{}
236
-	src.backlinksMu.Unlock()
224
+func (c *item) addResult(r solver.CacheExportResult) {
225
+	var exists bool
226
+	for _, rr := range c.results {
227
+		if !rr.CreatedAt.Equal(r.CreatedAt) {
228
+			continue
229
+		}
230
+		if len(rr.Result.Descriptors) != len(r.Result.Descriptors) {
231
+			continue
232
+		}
233
+		for i, d := range rr.Result.Descriptors {
234
+			if d.Digest != r.Result.Descriptors[i].Digest {
235
+				continue
236
+			}
237
+		}
238
+		exists = true
239
+		break
240
+	}
241
+	if !exists {
242
+		c.results = append(c.results, r)
243
+	}
237 244
 }
238 245
 
239
-// validate checks if an item is valid (i.e. each index has at least one link)
240
-// and marks it as such.
241
-//
242
-// Essentially, if an index has no links, it means that this cache record is
243
-// unreachable by the cache importer, so we should remove it. Once we've marked
244
-// an item as invalid, we remove it from it's backlinks and check it's
245
-// validity again - since now this linked item may be unreachable too.
246
-func (c *item) validate() {
247
-	if c.invalid {
248
-		// early exit, if the item is already invalid, we've already gone
249
-		// through the backlinks
246
+func (c *item) computeID() {
247
+	if c.id != "" {
250 248
 		return
251 249
 	}
252 250
 
253
-	for _, m := range c.links {
254
-		// if an index has no links, there's no way to access this record, so
255
-		// mark it as invalid
256
-		if len(m) == 0 {
257
-			c.invalid = true
258
-			break
259
-		}
251
+	if len(c.parents) == 0 {
252
+		c.id = c.dgst.String()
253
+		return
260 254
 	}
261 255
 
262
-	if c.invalid {
263
-		for bl := range c.backlinks {
264
-			// remove ourselves from the backlinked item
265
-			changed := false
266
-			for _, m := range bl.links {
267
-				for l := range m {
268
-					if l.src == c {
269
-						delete(m, l)
270
-						changed = true
271
-					}
272
-				}
256
+	// deterministic ID
257
+	h := xxhash.New()
258
+	h.Write([]byte(c.dgst.String()))
259
+	h.Write([]byte{0})
260
+
261
+	for idx, m := range c.parents {
262
+		binary.Write(h, binary.LittleEndian, uint32(idx))
263
+		h.Write([]byte{0})
264
+		for l := range m {
265
+			if l.src.id == "" {
266
+				l.src.computeID()
273 267
 			}
268
+			h.Write([]byte(l.src.id))
269
+			h.Write([]byte{0})
270
+			h.Write([]byte(l.selector))
271
+			h.Write([]byte{0})
272
+		}
273
+	}
274
+	c.id = string(h.Sum(nil))
275
+}
276
+
277
+func (c *item) bestResult() *solver.CacheExportResult {
278
+	if len(c.results) == 0 {
279
+		return nil
280
+	}
281
+	slices.SortFunc(c.results, func(a, b solver.CacheExportResult) int {
282
+		return b.CreatedAt.Compare(a.CreatedAt)
283
+	})
284
+	return &c.results[0]
285
+}
274 286
 
275
-			// if we've removed ourselves, we need to check it again
276
-			if changed {
277
-				bl.validate()
287
+func (c *item) walkChildren(fn func(i *item) error, visited map[*item]struct{}) error {
288
+	if _, ok := visited[c]; ok {
289
+		return nil
290
+	}
291
+	visited[c] = struct{}{}
292
+	if err := fn(c); err != nil {
293
+		return err
294
+	}
295
+	for _, ch := range c.children {
296
+		for it := range ch {
297
+			if err := it.walkChildren(fn, visited); err != nil {
298
+				return err
278 299
 			}
279 300
 		}
280 301
 	}
302
+	return nil
281 303
 }
282 304
 
283 305
 func (c *item) walkAllResults(fn func(i *item) error, visited map[*item]struct{}) error {
... ...
@@ -288,7 +423,7 @@ func (c *item) walkAllResults(fn func(i *item) error, visited map[*item]struct{}
288 288
 	if err := fn(c); err != nil {
289 289
 		return err
290 290
 	}
291
-	for _, links := range c.links {
291
+	for _, links := range c.parents {
292 292
 		for l := range links {
293 293
 			if err := l.src.walkAllResults(fn, visited); err != nil {
294 294
 				return err
... ...
@@ -297,13 +432,3 @@ func (c *item) walkAllResults(fn func(i *item) error, visited map[*item]struct{}
297 297
 	}
298 298
 	return nil
299 299
 }
300
-
301
-// nopRecord is used to discard cache results that we're not interested in storing.
302
-type nopRecord struct {
303
-}
304
-
305
-func (c *nopRecord) AddResult(_ digest.Digest, _ int, createdAt time.Time, result *solver.Remote) {
306
-}
307
-
308
-func (c *nopRecord) LinkFrom(rec solver.CacheExporterRecord, index int, selector string) {
309
-}
... ...
@@ -37,23 +37,32 @@ func parseRecord(cc CacheConfig, idx int, provider DescriptorProvider, t solver.
37 37
 		return r, nil
38 38
 	}
39 39
 
40
+	cache[idx] = nil
40 41
 	if idx < 0 || idx >= len(cc.Records) {
41 42
 		return nil, errors.Errorf("invalid record ID: %d", idx)
42 43
 	}
43 44
 	rec := cc.Records[idx]
44 45
 
45
-	r := t.Add(rec.Digest)
46
-	cache[idx] = nil
46
+	links := make([][]solver.CacheLink, len(rec.Inputs))
47
+
47 48
 	for i, inputs := range rec.Inputs {
48
-		for _, inp := range inputs {
49
+		if len(inputs) == 0 {
50
+			return nil, errors.Errorf("invalid empty input for record %d", idx)
51
+		}
52
+		links[i] = make([]solver.CacheLink, len(inputs))
53
+		for j, inp := range inputs {
49 54
 			src, err := parseRecord(cc, inp.LinkIndex, provider, t, cache)
50 55
 			if err != nil {
51 56
 				return nil, err
52 57
 			}
53
-			r.LinkFrom(src, i, inp.Selector)
58
+			links[i][j] = solver.CacheLink{
59
+				Selector: inp.Selector,
60
+				Src:      src,
61
+			}
54 62
 		}
55 63
 	}
56 64
 
65
+	results := make([]solver.CacheExportResult, 0, len(rec.Results))
57 66
 	for _, res := range rec.Results {
58 67
 		visited := map[int]struct{}{}
59 68
 		remote, err := getRemoteChain(cc.Layers, res.LayerIndex, provider, visited)
... ...
@@ -61,10 +70,12 @@ func parseRecord(cc CacheConfig, idx int, provider DescriptorProvider, t solver.
61 61
 			return nil, err
62 62
 		}
63 63
 		if remote != nil {
64
-			r.AddResult("", 0, res.CreatedAt, remote)
64
+			results = append(results, solver.CacheExportResult{
65
+				CreatedAt: res.CreatedAt,
66
+				Result:    remote,
67
+			})
65 68
 		}
66 69
 	}
67
-
68 70
 	for _, res := range rec.ChainedResults {
69 71
 		remote := &solver.Remote{}
70 72
 		mp := contentutil.NewMultiProvider(nil)
... ...
@@ -86,10 +97,17 @@ func parseRecord(cc CacheConfig, idx int, provider DescriptorProvider, t solver.
86 86
 		}
87 87
 		if remote != nil {
88 88
 			remote.Provider = mp
89
-			r.AddResult("", 0, res.CreatedAt, remote)
89
+			results = append(results, solver.CacheExportResult{
90
+				CreatedAt: res.CreatedAt,
91
+				Result:    remote,
92
+			})
90 93
 		}
91 94
 	}
92 95
 
96
+	r, _, err := t.Add(rec.Digest, links, results)
97
+	if err != nil {
98
+		return nil, errors.Wrapf(err, "failed to add record %d", idx)
99
+	}
93 100
 	cache[idx] = r
94 101
 	return r, nil
95 102
 }
... ...
@@ -23,7 +23,7 @@ type LayerAnnotations struct {
23 23
 	MediaType string        `json:"mediaType,omitempty"`
24 24
 	DiffID    digest.Digest `json:"diffID,omitempty"`
25 25
 	Size      int64         `json:"size,omitempty"`
26
-	CreatedAt time.Time     `json:"createdAt,omitempty"`
26
+	CreatedAt time.Time     `json:"createdAt"`
27 27
 }
28 28
 
29 29
 type CacheRecord struct {
... ...
@@ -35,12 +35,12 @@ type CacheRecord struct {
35 35
 
36 36
 type CacheResult struct {
37 37
 	LayerIndex int       `json:"layer"`
38
-	CreatedAt  time.Time `json:"createdAt,omitempty"`
38
+	CreatedAt  time.Time `json:"createdAt"`
39 39
 }
40 40
 
41 41
 type ChainedResult struct {
42 42
 	LayerIndexes []int     `json:"layers"`
43
-	CreatedAt    time.Time `json:"createdAt,omitempty"`
43
+	CreatedAt    time.Time `json:"createdAt"`
44 44
 }
45 45
 
46 46
 type CacheInput struct {
... ...
@@ -9,7 +9,6 @@ import (
9 9
 
10 10
 	cerrdefs "github.com/containerd/errdefs"
11 11
 	"github.com/moby/buildkit/solver"
12
-	"github.com/moby/buildkit/util/bklog"
13 12
 	digest "github.com/opencontainers/go-digest"
14 13
 	"github.com/pkg/errors"
15 14
 )
... ...
@@ -118,149 +117,6 @@ type nlink struct {
118 118
 	input    int
119 119
 	selector string
120 120
 }
121
-type normalizeState struct {
122
-	added map[*item]*item
123
-	links map[*item]map[nlink]map[digest.Digest]struct{}
124
-	byKey map[digest.Digest]*item
125
-	next  int
126
-}
127
-
128
-func (s *normalizeState) removeLoops(ctx context.Context) {
129
-	roots := []digest.Digest{}
130
-	for dgst, it := range s.byKey {
131
-		if len(it.links) == 0 {
132
-			roots = append(roots, dgst)
133
-		}
134
-	}
135
-
136
-	visited := map[digest.Digest]struct{}{}
137
-
138
-	for _, d := range roots {
139
-		s.checkLoops(ctx, d, visited)
140
-	}
141
-}
142
-
143
-func (s *normalizeState) checkLoops(ctx context.Context, d digest.Digest, visited map[digest.Digest]struct{}) {
144
-	it, ok := s.byKey[d]
145
-	if !ok {
146
-		return
147
-	}
148
-	links, ok := s.links[it]
149
-	if !ok {
150
-		return
151
-	}
152
-	visited[d] = struct{}{}
153
-	defer func() {
154
-		delete(visited, d)
155
-	}()
156
-
157
-	for l, ids := range links {
158
-		for id := range ids {
159
-			if _, ok := visited[id]; ok {
160
-				it2, ok := s.byKey[id]
161
-				if !ok {
162
-					continue
163
-				}
164
-				if !it2.removeLink(it) {
165
-					bklog.G(ctx).Warnf("failed to remove looping cache key %s %s", d, id)
166
-				}
167
-				delete(links[l], id)
168
-			} else {
169
-				s.checkLoops(ctx, id, visited)
170
-			}
171
-		}
172
-	}
173
-}
174
-
175
-func normalizeItem(it *item, state *normalizeState) (*item, error) {
176
-	if it2, ok := state.added[it]; ok {
177
-		return it2, nil
178
-	}
179
-
180
-	if len(it.links) == 0 {
181
-		id := it.dgst
182
-		if it2, ok := state.byKey[id]; ok {
183
-			state.added[it] = it2
184
-			return it2, nil
185
-		}
186
-		state.byKey[id] = it
187
-		state.added[it] = it
188
-		return nil, nil
189
-	}
190
-
191
-	matches := map[digest.Digest]struct{}{}
192
-
193
-	// check if there is already a matching record
194
-	for i, m := range it.links {
195
-		if len(m) == 0 {
196
-			return nil, errors.Errorf("invalid incomplete links")
197
-		}
198
-		for l := range m {
199
-			nl := nlink{dgst: it.dgst, input: i, selector: l.selector}
200
-			it2, err := normalizeItem(l.src, state)
201
-			if err != nil {
202
-				return nil, err
203
-			}
204
-			links := state.links[it2][nl]
205
-			if i == 0 {
206
-				for id := range links {
207
-					matches[id] = struct{}{}
208
-				}
209
-			} else {
210
-				for id := range matches {
211
-					if _, ok := links[id]; !ok {
212
-						delete(matches, id)
213
-					}
214
-				}
215
-			}
216
-		}
217
-	}
218
-
219
-	var id digest.Digest
220
-
221
-	links := it.links
222
-
223
-	if len(matches) > 0 {
224
-		for m := range matches {
225
-			if id == "" || id > m {
226
-				id = m
227
-			}
228
-		}
229
-	} else {
230
-		// keep tmp IDs deterministic
231
-		state.next++
232
-		id = digest.FromBytes(fmt.Appendf(nil, "%d", state.next))
233
-		state.byKey[id] = it
234
-		it.links = make([]map[link]struct{}, len(it.links))
235
-		for i := range it.links {
236
-			it.links[i] = map[link]struct{}{}
237
-		}
238
-	}
239
-
240
-	it2 := state.byKey[id]
241
-	state.added[it] = it2
242
-
243
-	for i, m := range links {
244
-		for l := range m {
245
-			subIt, err := normalizeItem(l.src, state)
246
-			if err != nil {
247
-				return nil, err
248
-			}
249
-			it2.links[i][link{src: subIt, selector: l.selector}] = struct{}{}
250
-
251
-			nl := nlink{dgst: it.dgst, input: i, selector: l.selector}
252
-			if _, ok := state.links[subIt]; !ok {
253
-				state.links[subIt] = map[nlink]map[digest.Digest]struct{}{}
254
-			}
255
-			if _, ok := state.links[subIt][nl]; !ok {
256
-				state.links[subIt][nl] = map[digest.Digest]struct{}{}
257
-			}
258
-			state.links[subIt][nl][id] = struct{}{}
259
-		}
260
-	}
261
-
262
-	return it2, nil
263
-}
264 121
 
265 122
 type marshalState struct {
266 123
 	layers      []CacheLayer
... ...
@@ -323,13 +179,14 @@ func marshalItem(ctx context.Context, it *item, state *marshalState) error {
323 323
 	if _, ok := state.recordsByItem[it]; ok {
324 324
 		return nil
325 325
 	}
326
+	state.recordsByItem[it] = -1
326 327
 
327 328
 	rec := CacheRecord{
328 329
 		Digest: it.dgst,
329
-		Inputs: make([][]CacheInput, len(it.links)),
330
+		Inputs: make([][]CacheInput, len(it.parents)),
330 331
 	}
331 332
 
332
-	for i, m := range it.links {
333
+	for i, m := range it.parents {
333 334
 		for l := range m {
334 335
 			if err := marshalItem(ctx, l.src, state); err != nil {
335 336
 				return err
... ...
@@ -338,6 +195,9 @@ func marshalItem(ctx context.Context, it *item, state *marshalState) error {
338 338
 			if !ok {
339 339
 				return errors.Errorf("invalid source record: %v", l.src)
340 340
 			}
341
+			if idx == -1 {
342
+				continue
343
+			}
341 344
 			rec.Inputs[i] = append(rec.Inputs[i], CacheInput{
342 345
 				Selector:  l.selector,
343 346
 				LinkIndex: idx,
... ...
@@ -345,14 +205,14 @@ func marshalItem(ctx context.Context, it *item, state *marshalState) error {
345 345
 		}
346 346
 	}
347 347
 
348
-	if it.result != nil {
349
-		id := marshalRemote(ctx, it.result, state)
348
+	if res := it.bestResult(); res != nil {
349
+		id := marshalRemote(ctx, res.Result, state)
350 350
 		if id != "" {
351 351
 			idx, ok := state.chainsByID[id]
352 352
 			if !ok {
353 353
 				return errors.Errorf("parent chainid not found")
354 354
 			}
355
-			rec.Results = append(rec.Results, CacheResult{LayerIndex: idx, CreatedAt: it.resultTime})
355
+			rec.Results = append(rec.Results, CacheResult{LayerIndex: idx, CreatedAt: res.CreatedAt})
356 356
 		}
357 357
 	}
358 358
 
... ...
@@ -24,7 +24,7 @@ type VertexStatus struct {
24 24
 	Name      string        `json:"name,omitempty"`
25 25
 	Total     int64         `json:"total,omitempty"`
26 26
 	Current   int64         `json:"current"`
27
-	Timestamp time.Time     `json:"timestamp,omitempty"`
27
+	Timestamp time.Time     `json:"timestamp"`
28 28
 	Started   *time.Time    `json:"started,omitempty"`
29 29
 	Completed *time.Time    `json:"completed,omitempty"`
30 30
 }
... ...
@@ -2,6 +2,7 @@ package llb
2 2
 
3 3
 import (
4 4
 	"github.com/moby/buildkit/client/llb/sourceresolver"
5
+	digest "github.com/opencontainers/go-digest"
5 6
 )
6 7
 
7 8
 // WithMetaResolver adds a metadata resolver to an image
... ...
@@ -26,5 +27,11 @@ func WithLayerLimit(l int) ImageOption {
26 26
 	})
27 27
 }
28 28
 
29
+func WithImageChecksum(dgst digest.Digest) ImageOption {
30
+	return imageOptionFunc(func(ii *ImageInfo) {
31
+		ii.checksum = dgst
32
+	})
33
+}
34
+
29 35
 // ImageMetaResolver can resolve image config metadata from a reference
30 36
 type ImageMetaResolver = sourceresolver.ImageMetaResolver
... ...
@@ -130,6 +130,11 @@ func Image(ref string, opts ...ImageOption) State {
130 130
 		addCap(&info.Constraints, pb.CapSourceImageLayerLimit)
131 131
 	}
132 132
 
133
+	if info.checksum != "" {
134
+		attrs[pb.AttrImageChecksum] = info.checksum.String()
135
+		addCap(&info.Constraints, pb.CapSourceImageChecksum)
136
+	}
137
+
133 138
 	src := NewSource("docker-image://"+ref, attrs, info.Constraints) // controversial
134 139
 	if err != nil {
135 140
 		src.err = err
... ...
@@ -227,6 +232,7 @@ type ImageInfo struct {
227 227
 	resolveDigest bool
228 228
 	resolveMode   ResolveMode
229 229
 	layerLimit    *int
230
+	checksum      digest.Digest
230 231
 	RecordType    string
231 232
 }
232 233
 
... ...
@@ -623,11 +629,18 @@ func OCILayerLimit(limit int) OCILayoutOption {
623 623
 	})
624 624
 }
625 625
 
626
+func OCIChecksum(dgst digest.Digest) OCILayoutOption {
627
+	return ociLayoutOptionFunc(func(oi *OCILayoutInfo) {
628
+		oi.checksum = dgst
629
+	})
630
+}
631
+
626 632
 type OCILayoutInfo struct {
627 633
 	constraintsWrapper
628 634
 	sessionID  string
629 635
 	storeID    string
630 636
 	layerLimit *int
637
+	checksum   digest.Digest
631 638
 }
632 639
 
633 640
 type DiffType string
... ...
@@ -42,6 +42,10 @@ type Config struct {
42 42
 	} `toml:"frontend"`
43 43
 
44 44
 	System *SystemConfig `toml:"system"`
45
+
46
+	// ProvenanceEnvDir is the directory where extra config is loaded
47
+	// that is added to the provenance of builds. Defaults to /etc/buildkit/provenance.d/ ,
48
+	ProvenanceEnvDir string `toml:"provenanceEnvDir"`
45 49
 }
46 50
 
47 51
 type SystemConfig struct {
... ...
@@ -74,6 +74,7 @@ type Opt struct {
74 74
 	HistoryConfig             *config.HistoryConfig
75 75
 	GarbageCollect            func(context.Context) error
76 76
 	GracefulStop              <-chan struct{}
77
+	ProvenanceEnv             map[string]any
77 78
 }
78 79
 
79 80
 type Controller struct { // TODO: ControlService
... ...
@@ -114,6 +115,7 @@ func NewController(opt Opt) (*Controller, error) {
114 114
 		SessionManager:   opt.SessionManager,
115 115
 		Entitlements:     opt.Entitlements,
116 116
 		HistoryQueue:     hq,
117
+		ProvenanceEnv:    opt.ProvenanceEnv,
117 118
 	})
118 119
 	if err != nil {
119 120
 		return nil, errors.Wrap(err, "failed to create solver")
... ...
@@ -524,7 +526,7 @@ func (c *Controller) Solve(ctx context.Context, req *controlapi.SolveRequest) (*
524 524
 				params[k] = v
525 525
 			}
526 526
 		}
527
-		procs = append(procs, proc.ProvenanceProcessor(slsaVersion, params))
527
+		procs = append(procs, proc.ProvenanceProcessor(slsaVersion, params, c.opt.ProvenanceEnv))
528 528
 	}
529 529
 
530 530
 	resp, err := c.solver.Solve(ctx, req.Ref, req.Session, frontend.SolveRequest{
... ...
@@ -40,6 +40,7 @@ type containerdExecutor struct {
40 40
 	selinux          bool
41 41
 	traceSocket      string
42 42
 	rootless         bool
43
+	hypervIsolation  bool
43 44
 	runtime          *RuntimeInfo
44 45
 	cdiManager       *cdidevices.Manager
45 46
 }
... ...
@@ -73,6 +74,7 @@ type ExecutorOptions struct {
73 73
 	Selinux          bool
74 74
 	TraceSocket      string
75 75
 	Rootless         bool
76
+	HyperVIsolation  bool
76 77
 	Runtime          *RuntimeInfo
77 78
 	CDIManager       *cdidevices.Manager
78 79
 }
... ...
@@ -94,6 +96,7 @@ func New(executorOpts ExecutorOptions) executor.Executor {
94 94
 		selinux:          executorOpts.Selinux,
95 95
 		traceSocket:      executorOpts.TraceSocket,
96 96
 		rootless:         executorOpts.Rootless,
97
+		hypervIsolation:  executorOpts.HyperVIsolation,
97 98
 		runtime:          executorOpts.Runtime,
98 99
 		cdiManager:       executorOpts.CDIManager,
99 100
 	}
... ...
@@ -80,6 +80,9 @@ func (w *containerdExecutor) createOCISpec(ctx context.Context, id, _, _ string,
80 80
 	opts := []containerdoci.SpecOpts{
81 81
 		containerdoci.WithUser(meta.User),
82 82
 	}
83
+	if w.hypervIsolation {
84
+		opts = append(opts, containerdoci.WithWindowsHyperV)
85
+	}
83 86
 
84 87
 	processMode := oci.ProcessSandbox // FIXME(AkihiroSuda)
85 88
 	spec, cleanup, err := oci.GenerateSpec(ctx, meta, mounts, id, "", "", namespace, "", processMode, nil, "", false, w.traceSocket, nil, opts...)
... ...
@@ -35,8 +35,8 @@ func getCgroupIOStat(cgroupPath string) (*resourcestypes.IOStat, error) {
35 35
 	}
36 36
 
37 37
 	ioStat := &resourcestypes.IOStat{}
38
-	lines := strings.Split(string(data), "\n")
39
-	for _, line := range lines {
38
+	lines := strings.SplitSeq(string(data), "\n")
39
+	for line := range lines {
40 40
 		parts := strings.Fields(line)
41 41
 		if len(parts) < 2 {
42 42
 			continue
... ...
@@ -138,8 +138,8 @@ func parseKeyValueFile(filePath string, callback func(key string, value uint64))
138 138
 		return errors.Wrapf(err, "failed to read %s", filePath)
139 139
 	}
140 140
 
141
-	lines := strings.Split(string(content), "\n")
142
-	for _, line := range lines {
141
+	lines := strings.SplitSeq(string(content), "\n")
142
+	for line := range lines {
143 143
 		if len(strings.TrimSpace(line)) == 0 {
144 144
 			continue
145 145
 		}
... ...
@@ -273,7 +273,7 @@ func prepareCgroupControllers() error {
273 273
 	if err != nil {
274 274
 		return err
275 275
 	}
276
-	for _, c := range strings.Split(string(dt), " ") {
276
+	for c := range strings.SplitSeq(string(dt), " ") {
277 277
 		if c == "" {
278 278
 			continue
279 279
 		}
... ...
@@ -271,8 +271,8 @@ func (e *imageExporterInstance) Export(ctx context.Context, src *exporter.Source
271 271
 	}
272 272
 
273 273
 	if e.opts.ImageName != "" {
274
-		targetNames := strings.Split(e.opts.ImageName, ",")
275
-		for _, targetName := range targetNames {
274
+		targetNames := strings.SplitSeq(e.opts.ImageName, ",")
275
+		for targetName := range targetNames {
276 276
 			if e.opt.Images != nil && e.store {
277 277
 				tagDone := progress.OneOff(ctx, "naming to "+targetName)
278 278
 
... ...
@@ -296,7 +296,7 @@ func (ic *ImageWriter) Commit(ctx context.Context, inp *exporter.Source, session
296 296
 			}
297 297
 
298 298
 			var defaultSubjects []intoto.Subject
299
-			for _, name := range strings.Split(opts.ImageName, ",") {
299
+			for name := range strings.SplitSeq(opts.ImageName, ",") {
300 300
 				if name == "" {
301 301
 					continue
302 302
 				}
... ...
@@ -617,7 +617,11 @@ func (ic *ImageWriter) commitAttestationsManifest(ctx context.Context, opts *Ima
617 617
 
618 618
 	if ociArtifact {
619 619
 		mfst.ArtifactType = attestationManifestArtifactType
620
-		mfst.Subject = &target
620
+		mfst.Subject = &ocispecs.Descriptor{
621
+			Digest:    target.Digest,
622
+			Size:      target.Size,
623
+			MediaType: target.MediaType,
624
+		}
621 625
 	}
622 626
 
623 627
 	labels := map[string]string{
... ...
@@ -20,8 +20,8 @@ func validateCaps(req string) (forward bool, err error) {
20 20
 	if req == "" {
21 21
 		return
22 22
 	}
23
-	caps := strings.Split(req, ",")
24
-	for _, c := range caps {
23
+	caps := strings.SplitSeq(req, ",")
24
+	for c := range caps {
25 25
 		parts := strings.SplitN(c, "+", 2)
26 26
 		if _, ok := enabledCaps[parts[0]]; !ok {
27 27
 			err = stack.Enable(grpcerrors.WrapCode(errdefs.NewUnsupportedFrontendCapError(parts[0]), codes.Unimplemented))
... ...
@@ -41,7 +41,7 @@ func dispatchExpose(d *dispatchState, c *instructions.ExposeCommand, opt *dispat
41 41
 		d.image.Config.ExposedPorts[p] = struct{}{}
42 42
 	}
43 43
 
44
-	return commitToHistory(&d.image, fmt.Sprintf("EXPOSE %v", ps), false, nil, d.epoch)
44
+	return commitToHistory(&d.image, fmt.Sprintf("EXPOSE %v", psp), false, nil, d.epoch)
45 45
 }
46 46
 
47 47
 type portSpecs struct {
48 48
deleted file mode 100644
... ...
@@ -1,7 +0,0 @@
1
-//go:build dfexcludepatterns
2
-
3
-package instructions
4
-
5
-func init() {
6
-	excludePatternsEnabled = true
7
-}
... ...
@@ -20,8 +20,6 @@ import (
20 20
 	"github.com/pkg/errors"
21 21
 )
22 22
 
23
-var excludePatternsEnabled = false
24
-
25 23
 type parseRequest struct {
26 24
 	command    string
27 25
 	args       []string
... ...
@@ -33,8 +31,10 @@ type parseRequest struct {
33 33
 	comments   []string
34 34
 }
35 35
 
36
-var parseRunPreHooks []func(*RunCommand, parseRequest) error
37
-var parseRunPostHooks []func(*RunCommand, parseRequest) error
36
+var (
37
+	parseRunPreHooks  []func(*RunCommand, parseRequest) error
38
+	parseRunPostHooks []func(*RunCommand, parseRequest) error
39
+)
38 40
 
39 41
 var parentsEnabled = false
40 42
 
... ...
@@ -326,19 +326,13 @@ func parseAdd(req parseRequest) (*AddCommand, error) {
326 326
 		return nil, errNoDestinationArgument("ADD")
327 327
 	}
328 328
 
329
-	var flExcludes *Flag
330
-
331
-	// silently ignore if not -labs
332
-	if excludePatternsEnabled {
333
-		flExcludes = req.flags.AddStrings("exclude")
334
-	}
335
-
336 329
 	flChown := req.flags.AddString("chown", "")
337 330
 	flChmod := req.flags.AddString("chmod", "")
338 331
 	flLink := req.flags.AddBool("link", false)
339 332
 	flKeepGitDir := req.flags.AddBool("keep-git-dir", false)
340 333
 	flChecksum := req.flags.AddString("checksum", "")
341 334
 	flUnpack := req.flags.AddBool("unpack", false)
335
+	flExcludes := req.flags.AddStrings("exclude")
342 336
 	if err := req.flags.Parse(); err != nil {
343 337
 		return nil, err
344 338
 	}
... ...
@@ -378,12 +372,7 @@ func parseCopy(req parseRequest) (*CopyCommand, error) {
378 378
 		return nil, errNoDestinationArgument("COPY")
379 379
 	}
380 380
 
381
-	var flExcludes *Flag
382 381
 	var flParents *Flag
383
-
384
-	if excludePatternsEnabled {
385
-		flExcludes = req.flags.AddStrings("exclude")
386
-	}
387 382
 	if parentsEnabled {
388 383
 		flParents = req.flags.AddBool("parents", false)
389 384
 	}
... ...
@@ -392,6 +381,7 @@ func parseCopy(req parseRequest) (*CopyCommand, error) {
392 392
 	flFrom := req.flags.AddString("from", "")
393 393
 	flChmod := req.flags.AddString("chmod", "")
394 394
 	flLink := req.flags.AddBool("link", false)
395
+	flExcludes := req.flags.AddStrings("exclude")
395 396
 
396 397
 	if err := req.flags.Parse(); err != nil {
397 398
 		return nil, err
... ...
@@ -602,6 +592,7 @@ func parseOptInterval(f *Flag) (time.Duration, error) {
602 602
 	}
603 603
 	return d, nil
604 604
 }
605
+
605 606
 func parseHealthcheck(req parseRequest) (*HealthCheckCommand, error) {
606 607
 	if len(req.args) == 0 {
607 608
 		return nil, errAtLeastOneArgument("HEALTHCHECK")
... ...
@@ -17,7 +17,7 @@ import (
17 17
 
18 18
 func parsePlatforms(v string) ([]ocispecs.Platform, error) {
19 19
 	var pp []ocispecs.Platform
20
-	for _, v := range strings.Split(v, ",") {
20
+	for v := range strings.SplitSeq(v, ",") {
21 21
 		p, err := platforms.Parse(v)
22 22
 		if err != nil {
23 23
 			return nil, errors.Wrapf(err, "failed to parse target platform %s", v)
... ...
@@ -237,8 +237,8 @@ func (bc *Client) init() error {
237 237
 	}
238 238
 	// old API
239 239
 	if cacheFromStr := opts[keyCacheFrom]; cacheFromStr != "" {
240
-		cacheFrom := strings.Split(cacheFromStr, ",")
241
-		for _, s := range cacheFrom {
240
+		cacheFrom := strings.SplitSeq(cacheFromStr, ",")
241
+		for s := range cacheFrom {
242 242
 			im := client.CacheOptionsEntry{
243 243
 				Type: "registry",
244 244
 				Attrs: map[string]string{
... ...
@@ -898,7 +898,7 @@ func (lbf *llbBridgeForwarder) getImmutableRef(ctx context.Context, id string) (
898 898
 		}
899 899
 		if ref == nil {
900 900
 			lbf.mu.Unlock()
901
-			return nil, errors.Errorf("no such ref: %s, all %+v", id, maps.Keys(lbf.refs))
901
+			return nil, errors.Errorf("no such ref: %s, all %+v", id, slices.Collect(maps.Keys(lbf.refs)))
902 902
 		}
903 903
 	}
904 904
 	lbf.mu.Unlock()
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/frontend/gateway/pb/gateway.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/session/auth/auth.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/session/exporter/exporter.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/session/filesync/filesync.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/session/secrets/secrets.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/session/sshforward/ssh.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/session/upload/upload.proto
6 6
 
... ...
@@ -946,19 +946,19 @@ func (e *edge) loadCache(ctx context.Context) (any, error) {
946 946
 	e.cacheRecordsLoaded[rec.ID] = struct{}{}
947 947
 
948 948
 	bklog.G(ctx).Debugf("load cache for %s with %s", e.edge.Vertex.Name(), rec.ID)
949
-	res, err := e.op.LoadCache(ctx, rec)
949
+	res, ctxOpts, err := e.op.LoadCache(ctx, rec)
950 950
 	if err != nil {
951 951
 		bklog.G(ctx).Debugf("load cache for %s err: %v", e.edge.Vertex.Name(), err)
952 952
 		return nil, errors.Wrap(err, "failed to load cache")
953 953
 	}
954 954
 
955
-	return NewCachedResult(res, []ExportableCacheKey{{CacheKey: rec.key, Exporter: &exporter{k: rec.key, record: rec, edge: e}}}), nil
955
+	return NewCachedResult(res, []ExportableCacheKey{{CacheKey: rec.key, Exporter: &exporter{k: rec.key, record: rec, edge: e, recordCtxOpts: ctxOpts}}}), nil
956 956
 }
957 957
 
958 958
 // execOp creates a request to execute the vertex operation
959 959
 func (e *edge) execOp(ctx context.Context) (any, error) {
960 960
 	cacheKeys, inputs := e.commitOptions()
961
-	results, subExporters, err := e.op.Exec(ctx, toResultSlice(inputs))
961
+	results, subExporters, ctxOpts, err := e.op.Exec(ctx, toResultSlice(inputs))
962 962
 	if err != nil {
963 963
 		return nil, errors.WithStack(err)
964 964
 	}
... ...
@@ -986,6 +986,7 @@ func (e *edge) execOp(ctx context.Context) (any, error) {
986 986
 
987 987
 		if exp, ok := ck.Exporter.(*exporter); ok {
988 988
 			exp.edge = e
989
+			exp.recordCtxOpts = ctxOpts
989 990
 		}
990 991
 
991 992
 		exps := make([]CacheExporter, 0, len(subExporters))
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/solver/errdefs/errdefs.proto
6 6
 
... ...
@@ -9,63 +9,102 @@ import (
9 9
 )
10 10
 
11 11
 type exporter struct {
12
-	k       *CacheKey
13
-	records []*CacheRecord
14
-	record  *CacheRecord
12
+	k             *CacheKey
13
+	records       []*CacheRecord
14
+	record        *CacheRecord
15
+	recordCtxOpts func(context.Context) context.Context
15 16
 
16 17
 	edge     *edge // for secondaryExporters
17 18
 	override *bool
18 19
 }
19 20
 
20
-func addBacklinks(t CacheExporterTarget, rec CacheExporterRecord, cm *cacheManager, id string, bkm map[string]CacheExporterRecord) (CacheExporterRecord, error) {
21
-	if rec == nil {
22
-		var ok bool
23
-		rec, ok = bkm[id]
24
-		if ok && rec != nil {
25
-			return rec, nil
26
-		}
27
-		_ = ok
21
+func addBacklinks(t CacheExporterTarget, cm *cacheManager, id string, bkm map[string][]CacheExporterRecord) ([]CacheExporterRecord, error) {
22
+	out, ok := bkm[id]
23
+	if ok && out != nil {
24
+		return out, nil
25
+	} else if ok && out == nil {
26
+		return nil, nil
28 27
 	}
29 28
 	bkm[id] = nil
29
+
30
+	m := map[digest.Digest][][]CacheLink{}
31
+	isRoot := true
30 32
 	if err := cm.backend.WalkBacklinks(id, func(id string, link CacheInfoLink) error {
31
-		if rec == nil {
32
-			rec = t.Add(link.Digest)
33
+		isRoot = false
34
+		recs, err := addBacklinks(t, cm, id, bkm)
35
+		if err != nil { // TODO: should we continue on error?
36
+			return err
33 37
 		}
34
-		r, ok := bkm[id]
35
-		if !ok {
36
-			var err error
37
-			r, err = addBacklinks(t, nil, cm, id, bkm)
38
-			if err != nil {
39
-				return err
40
-			}
38
+		links := m[link.Digest]
39
+		for int(link.Input) >= len(links) {
40
+			links = append(links, nil)
41 41
 		}
42
-		if r != nil {
43
-			rec.LinkFrom(r, int(link.Input), link.Selector.String())
42
+		for _, rec := range recs {
43
+			links[int(link.Input)] = append(links[int(link.Input)], CacheLink{Src: rec, Selector: link.Selector.String()})
44 44
 		}
45
+		m[link.Digest] = links
45 46
 		return nil
46 47
 	}); err != nil {
47 48
 		return nil, err
48 49
 	}
49
-	if rec == nil {
50
-		rec = t.Add(digest.Digest(id))
50
+
51
+	if isRoot {
52
+		dgst, err := digest.Parse(id)
53
+		if err == nil {
54
+			rec, ok, err := t.Add(dgst, nil, nil)
55
+			if err != nil {
56
+				return nil, err
57
+			}
58
+			if ok && rec != nil {
59
+				out = append(out, rec)
60
+			}
61
+		}
51 62
 	}
52
-	bkm[id] = rec
53
-	return rec, nil
63
+
64
+	// validate that all inputs are present
65
+	for dgst, links := range m {
66
+		for _, links := range links {
67
+			if len(links) == 0 {
68
+				out = nil
69
+				m[dgst] = nil
70
+				break
71
+			}
72
+		}
73
+	}
74
+
75
+	for dgst, links := range m {
76
+		if len(links) == 0 {
77
+			continue
78
+		}
79
+		rec, ok, err := t.Add(dgst, links, nil)
80
+		if err != nil {
81
+			return nil, err
82
+		}
83
+		if !ok || rec == nil {
84
+			continue
85
+		}
86
+		out = append(out, rec)
87
+	}
88
+
89
+	bkm[id] = out
90
+	return out, nil
54 91
 }
55 92
 
56 93
 type contextT string
57 94
 
58
-var backlinkKey = contextT("solver/exporter/backlinks")
59
-var resKey = contextT("solver/exporter/res")
95
+var (
96
+	backlinkKey = contextT("solver/exporter/backlinks")
97
+	resKey      = contextT("solver/exporter/res")
98
+)
60 99
 
61 100
 func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt CacheExportOpt) ([]CacheExporterRecord, error) {
62
-	var bkm map[string]CacheExporterRecord
101
+	var bkm map[string][]CacheExporterRecord
63 102
 
64 103
 	if bk := ctx.Value(backlinkKey); bk == nil {
65
-		bkm = map[string]CacheExporterRecord{}
104
+		bkm = map[string][]CacheExporterRecord{}
66 105
 		ctx = context.WithValue(ctx, backlinkKey, bkm)
67 106
 	} else {
68
-		bkm = bk.(map[string]CacheExporterRecord)
107
+		bkm = bk.(map[string][]CacheExporterRecord)
69 108
 	}
70 109
 
71 110
 	var res map[*exporter][]CacheExporterRecord
... ...
@@ -75,23 +114,17 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach
75 75
 	} else {
76 76
 		res = r.(map[*exporter][]CacheExporterRecord)
77 77
 	}
78
-
79
-	if t.Visited(e) {
80
-		return res[e], nil
78
+	if v, ok := res[e]; ok {
79
+		return v, nil
81 80
 	}
82
-	t.Visit(e)
81
+	res[e] = nil
83 82
 
84 83
 	deps := e.k.Deps()
85 84
 
86
-	type expr struct {
87
-		r        CacheExporterRecord
88
-		selector digest.Digest
89
-	}
90 85
 	k := e.k.clone() // protect against *CacheKey internal ids mutation from other exports
91 86
 
92 87
 	recKey := rootKey(k.Digest(), k.Output())
93
-	rec := t.Add(recKey)
94
-	allRec := []CacheExporterRecord{rec}
88
+	results := []CacheExportResult{}
95 89
 
96 90
 	addRecord := true
97 91
 
... ...
@@ -109,9 +142,13 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach
109 109
 
110 110
 	var remote *Remote
111 111
 	var i int
112
+
113
+	mainCtx := ctx
114
+	if CacheOptGetterOf(ctx) == nil && e.recordCtxOpts != nil {
115
+		ctx = e.recordCtxOpts(ctx)
116
+	}
117
+	v := e.record
112 118
 	for exportRecord && addRecord {
113
-		var variants []CacheExporterRecord
114
-		v := e.record
115 119
 		if v == nil {
116 120
 			if i < len(records) {
117 121
 				v = records[i]
... ...
@@ -125,6 +162,7 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach
125 125
 		res, err := cm.backend.Load(key, v.ID)
126 126
 		if err != nil {
127 127
 			if errors.Is(err, ErrNotFound) {
128
+				v = nil
128 129
 				continue
129 130
 			}
130 131
 			return nil, err
... ...
@@ -139,9 +177,12 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach
139 139
 		}
140 140
 		if opt.CompressionOpt != nil {
141 141
 			for _, r := range remotes { // record all remaining remotes as well
142
-				rec := t.Add(recKey)
143
-				rec.AddResult(k.vtx, int(k.output), v.CreatedAt, r)
144
-				variants = append(variants, rec)
142
+				results = append(results, CacheExportResult{
143
+					CreatedAt:  v.CreatedAt,
144
+					Result:     r,
145
+					EdgeVertex: k.vtx,
146
+					EdgeIndex:  k.output,
147
+				})
145 148
 			}
146 149
 		}
147 150
 
... ...
@@ -160,19 +201,24 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach
160 160
 			}
161 161
 			if opt.CompressionOpt != nil {
162 162
 				for _, r := range remotes { // record all remaining remotes as well
163
-					rec := t.Add(recKey)
164
-					rec.AddResult(k.vtx, int(k.output), v.CreatedAt, r)
165
-					variants = append(variants, rec)
163
+					results = append(results, CacheExportResult{
164
+						CreatedAt:  v.CreatedAt,
165
+						Result:     r,
166
+						EdgeVertex: k.vtx,
167
+						EdgeIndex:  k.output,
168
+					})
166 169
 				}
167 170
 			}
168 171
 		}
169 172
 
170 173
 		if remote != nil {
171
-			for _, rec := range allRec {
172
-				rec.AddResult(k.vtx, int(k.output), v.CreatedAt, remote)
173
-			}
174
+			results = append(results, CacheExportResult{
175
+				CreatedAt:  v.CreatedAt,
176
+				Result:     remote,
177
+				EdgeVertex: k.vtx,
178
+				EdgeIndex:  k.output,
179
+			})
174 180
 		}
175
-		allRec = append(allRec, variants...)
176 181
 		break
177 182
 	}
178 183
 
... ...
@@ -180,65 +226,77 @@ func (e *exporter) ExportTo(ctx context.Context, t CacheExporterTarget, opt Cach
180 180
 		opt.Mode = CacheExportModeRemoteOnly
181 181
 	}
182 182
 
183
-	srcs := make([][]expr, len(deps))
183
+	srcs := make([][]CacheLink, len(deps))
184 184
 
185 185
 	for i, deps := range deps {
186 186
 		for _, dep := range deps {
187
-			recs, err := dep.CacheKey.Exporter.ExportTo(ctx, t, opt)
187
+			rec, err := dep.CacheKey.Exporter.ExportTo(ctx, t, opt)
188 188
 			if err != nil {
189
-				return nil, nil
189
+				return nil, err
190 190
 			}
191
-			for _, r := range recs {
192
-				srcs[i] = append(srcs[i], expr{r: r, selector: dep.Selector})
191
+			for _, r := range rec {
192
+				srcs[i] = append(srcs[i], CacheLink{Src: r, Selector: string(dep.Selector)})
193 193
 			}
194 194
 		}
195 195
 	}
196 196
 
197 197
 	if e.edge != nil {
198 198
 		for _, de := range e.edge.secondaryExporters {
199
-			recs, err := de.cacheKey.CacheKey.Exporter.ExportTo(ctx, t, opt)
199
+			recs, err := de.cacheKey.CacheKey.Exporter.ExportTo(mainCtx, t, opt)
200 200
 			if err != nil {
201 201
 				return nil, nil
202 202
 			}
203 203
 			for _, r := range recs {
204
-				srcs[de.index] = append(srcs[de.index], expr{r: r, selector: de.cacheKey.Selector})
204
+				srcs[de.index] = append(srcs[de.index], CacheLink{Src: r, Selector: de.cacheKey.Selector.String()})
205 205
 			}
206 206
 		}
207 207
 	}
208 208
 
209
-	for _, rec := range allRec {
210
-		for i, srcs := range srcs {
211
-			for _, src := range srcs {
212
-				rec.LinkFrom(src.r, i, src.selector.String())
213
-			}
214
-		}
215
-
216
-		if !opt.IgnoreBacklinks {
217
-			for cm, id := range k.ids {
218
-				if _, err := addBacklinks(t, rec, cm, id, bkm); err != nil {
219
-					return nil, err
220
-				}
209
+	if !opt.IgnoreBacklinks {
210
+		for cm, id := range k.ids {
211
+			_, err := addBacklinks(t, cm, id, bkm)
212
+			if err != nil {
213
+				return nil, err
221 214
 			}
222 215
 		}
223 216
 	}
224 217
 
225
-	if v := e.record; v != nil && len(deps) == 0 {
218
+	if v != nil && len(deps) == 0 {
226 219
 		cm := v.cacheManager
227 220
 		key := cm.getID(v.key)
228 221
 		if err := cm.backend.WalkIDsByResult(v.ID, func(id string) error {
229 222
 			if id == key {
230 223
 				return nil
231 224
 			}
232
-			allRec = append(allRec, t.Add(digest.Digest(id)))
233
-			return nil
225
+			hasBacklinks := false
226
+			cm.backend.WalkBacklinks(id, func(id string, link CacheInfoLink) error {
227
+				hasBacklinks = true
228
+				return nil
229
+			})
230
+			if hasBacklinks {
231
+				return nil
232
+			}
233
+
234
+			dgst, err := digest.Parse(id)
235
+			if err != nil {
236
+				return nil
237
+			}
238
+			_, _, err = t.Add(dgst, nil, results)
239
+			return err
234 240
 		}); err != nil {
235 241
 			return nil, err
236 242
 		}
237 243
 	}
238 244
 
239
-	res[e] = allRec
240
-
241
-	return allRec, nil
245
+	out, ok, err := t.Add(recKey, srcs, results)
246
+	if err != nil {
247
+		return nil, err
248
+	}
249
+	res[e] = []CacheExporterRecord{}
250
+	if ok {
251
+		res[e] = append(res[e], out)
252
+	}
253
+	return res[e], nil
242 254
 }
243 255
 
244 256
 func getBestResult(records []*CacheRecord) *CacheRecord {
... ...
@@ -843,8 +843,8 @@ type cacheMapResp struct {
843 843
 
844 844
 type activeOp interface {
845 845
 	CacheMap(context.Context, int) (*cacheMapResp, error)
846
-	LoadCache(ctx context.Context, rec *CacheRecord) (Result, error)
847
-	Exec(ctx context.Context, inputs []Result) (outputs []Result, exporters []ExportableCacheKey, err error)
846
+	LoadCache(ctx context.Context, rec *CacheRecord) (Result, func(context.Context) context.Context, error)
847
+	Exec(ctx context.Context, inputs []Result) (outputs []Result, exporters []ExportableCacheKey, ctxOpts func(context.Context) context.Context, err error)
848 848
 	IgnoreCache() bool
849 849
 	Cache() CacheManager
850 850
 	CalcSlowCache(context.Context, Index, PreprocessFunc, ResultBasedCacheFunc, Result) (digest.Digest, error)
... ...
@@ -909,7 +909,7 @@ func (c cacheWithCacheOpts) Records(ctx context.Context, ck *CacheKey) ([]*Cache
909 909
 	return c.CacheManager.Records(withAncestorCacheOpts(ctx, c.st), ck)
910 910
 }
911 911
 
912
-func (s *sharedOp) LoadCache(ctx context.Context, rec *CacheRecord) (Result, error) {
912
+func (s *sharedOp) LoadCache(ctx context.Context, rec *CacheRecord) (Result, func(context.Context) context.Context, error) {
913 913
 	ctx = progress.WithProgress(ctx, s.st.mpw)
914 914
 	if s.st.mspan.Span != nil {
915 915
 		ctx = trace.ContextWithSpan(ctx, s.st.mspan)
... ...
@@ -921,7 +921,9 @@ func (s *sharedOp) LoadCache(ctx context.Context, rec *CacheRecord) (Result, err
921 921
 	res, err := s.Cache().Load(withAncestorCacheOpts(ctx, s.st), rec)
922 922
 	tracing.FinishWithError(span, err)
923 923
 	notifyCompleted(err, true)
924
-	return res, err
924
+	return res, func(ctx context.Context) context.Context {
925
+		return withAncestorCacheOpts(ctx, s.st)
926
+	}, err
925 927
 }
926 928
 
927 929
 // CalcSlowCache computes the digest of an input that is ready and has been
... ...
@@ -1079,14 +1081,14 @@ func (s *sharedOp) CacheMap(ctx context.Context, index int) (resp *cacheMapResp,
1079 1079
 	return &cacheMapResp{CacheMap: res[index], complete: s.cacheDone}, nil
1080 1080
 }
1081 1081
 
1082
-func (s *sharedOp) Exec(ctx context.Context, inputs []Result) (outputs []Result, exporters []ExportableCacheKey, err error) {
1082
+func (s *sharedOp) Exec(ctx context.Context, inputs []Result) (outputs []Result, exporters []ExportableCacheKey, ctxOpts func(context.Context) context.Context, err error) {
1083 1083
 	defer func() {
1084 1084
 		err = errdefs.WithOp(err, s.st.vtx.Sys(), s.st.vtx.Options().Description)
1085 1085
 		err = errdefs.WrapVertex(err, s.st.origDigest)
1086 1086
 	}()
1087 1087
 	op, err := s.getOp()
1088 1088
 	if err != nil {
1089
-		return nil, nil, err
1089
+		return nil, nil, nil, err
1090 1090
 	}
1091 1091
 	flightControlKey := "exec"
1092 1092
 	res, err := s.gExecRes.Do(ctx, flightControlKey, func(ctx context.Context) (ret *execRes, retErr error) {
... ...
@@ -1150,9 +1152,11 @@ func (s *sharedOp) Exec(ctx context.Context, inputs []Result) (outputs []Result,
1150 1150
 		return s.execRes, nil
1151 1151
 	})
1152 1152
 	if res == nil || err != nil {
1153
-		return nil, nil, err
1153
+		return nil, nil, nil, err
1154 1154
 	}
1155
-	return unwrapShared(res.execRes), res.execExporters, nil
1155
+	return unwrapShared(res.execRes), res.execExporters, func(ctx context.Context) context.Context {
1156
+		return withAncestorCacheOpts(ctx, s.st)
1157
+	}, nil
1156 1158
 }
1157 1159
 
1158 1160
 func (s *sharedOp) getOp() (Op, error) {
... ...
@@ -16,7 +16,7 @@ import (
16 16
 	"github.com/pkg/errors"
17 17
 )
18 18
 
19
-func ProvenanceProcessor(slsaVersion provenancetypes.ProvenanceSLSA, attrs map[string]string) llbsolver.Processor {
19
+func ProvenanceProcessor(slsaVersion provenancetypes.ProvenanceSLSA, attrs map[string]string, customEnv map[string]any) llbsolver.Processor {
20 20
 	return func(ctx context.Context, res *llbsolver.Result, s *llbsolver.Solver, j *solver.Job, usage *resources.SysSampler) (*llbsolver.Result, error) {
21 21
 		span, ctx := tracing.StartSpan(ctx, "create provenance attestation")
22 22
 		defer span.End()
... ...
@@ -46,7 +46,7 @@ func ProvenanceProcessor(slsaVersion provenancetypes.ProvenanceSLSA, attrs map[s
46 46
 				return nil, errors.Errorf("could not find ref %s", p.ID)
47 47
 			}
48 48
 
49
-			pc, err := llbsolver.NewProvenanceCreator(ctx, slsaVersion, cp, ref, attrs, j, usage)
49
+			pc, err := llbsolver.NewProvenanceCreator(ctx, slsaVersion, cp, ref, attrs, j, usage, customEnv)
50 50
 			if err != nil {
51 51
 				return nil, err
52 52
 			}
... ...
@@ -6,7 +6,6 @@ import (
6 6
 	"strconv"
7 7
 	"strings"
8 8
 	"sync"
9
-	"time"
10 9
 
11 10
 	"github.com/containerd/platforms"
12 11
 	slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
... ...
@@ -339,7 +338,7 @@ type ProvenanceCreator struct {
339 339
 	addLayers   func(context.Context) error
340 340
 }
341 341
 
342
-func NewProvenanceCreator(ctx context.Context, slsaVersion provenancetypes.ProvenanceSLSA, cp *provenance.Capture, res solver.ResultProxy, attrs map[string]string, j *solver.Job, usage *resources.SysSampler) (*ProvenanceCreator, error) {
342
+func NewProvenanceCreator(ctx context.Context, slsaVersion provenancetypes.ProvenanceSLSA, cp *provenance.Capture, res solver.ResultProxy, attrs map[string]string, j *solver.Job, usage *resources.SysSampler, customEnv map[string]any) (*ProvenanceCreator, error) {
343 343
 	var reproducible bool
344 344
 	if v, ok := attrs["reproducible"]; ok {
345 345
 		b, err := strconv.ParseBool(v)
... ...
@@ -451,6 +450,8 @@ func NewProvenanceCreator(ctx context.Context, slsaVersion provenancetypes.Prove
451 451
 		return nil, errors.Errorf("invalid mode %q", mode)
452 452
 	}
453 453
 
454
+	pr.Invocation.Environment.ProvenanceCustomEnv = customEnv
455
+
454 456
 	pc := &ProvenanceCreator{
455 457
 		pr:          pr,
456 458
 		slsaVersion: slsaVersion,
... ...
@@ -512,43 +513,28 @@ type cacheExporter struct {
512 512
 	m      map[any]struct{}
513 513
 }
514 514
 
515
-func (ce *cacheExporter) Add(dgst digest.Digest) solver.CacheExporterRecord {
516
-	return &cacheRecord{
517
-		ce: ce,
515
+func (ce *cacheExporter) Add(dgst digest.Digest, deps [][]solver.CacheLink, results []solver.CacheExportResult) (solver.CacheExporterRecord, bool, error) {
516
+	for _, res := range results {
517
+		if res.EdgeVertex == "" {
518
+			continue
519
+		}
520
+		e := edge{
521
+			digest: res.EdgeVertex,
522
+			index:  int(res.EdgeIndex),
523
+		}
524
+		descs := make([]ocispecs.Descriptor, len(res.Result.Descriptors))
525
+		for i, desc := range res.Result.Descriptors {
526
+			d := desc
527
+			d.Annotations = containerimage.RemoveInternalLayerAnnotations(d.Annotations, true)
528
+			descs[i] = d
529
+		}
530
+		ce.layers[e] = appendLayerChain(ce.layers[e], descs)
518 531
 	}
519
-}
520
-
521
-func (ce *cacheExporter) Visit(target any) {
522
-	ce.m[target] = struct{}{}
523
-}
524
-
525
-func (ce *cacheExporter) Visited(target any) bool {
526
-	_, ok := ce.m[target]
527
-	return ok
532
+	return &cacheRecord{}, true, nil
528 533
 }
529 534
 
530 535
 type cacheRecord struct {
531
-	ce *cacheExporter
532
-}
533
-
534
-func (c *cacheRecord) AddResult(dgst digest.Digest, idx int, createdAt time.Time, result *solver.Remote) {
535
-	if result == nil || dgst == "" {
536
-		return
537
-	}
538
-	e := edge{
539
-		digest: dgst,
540
-		index:  idx,
541
-	}
542
-	descs := make([]ocispecs.Descriptor, len(result.Descriptors))
543
-	for i, desc := range result.Descriptors {
544
-		d := desc
545
-		d.Annotations = containerimage.RemoveInternalLayerAnnotations(d.Annotations, true)
546
-		descs[i] = d
547
-	}
548
-	c.ce.layers[e] = appendLayerChain(c.ce.layers[e], descs)
549
-}
550
-
551
-func (c *cacheRecord) LinkFrom(rec solver.CacheExporterRecord, index int, selector string) {
536
+	solver.CacheExporterRecordBase
552 537
 }
553 538
 
554 539
 func resolveRemotes(ctx context.Context, res solver.Result) ([]*solver.Remote, error) {
... ...
@@ -1,12 +1,14 @@
1 1
 package provenance
2 2
 
3 3
 import (
4
+	"maps"
4 5
 	"strings"
5 6
 
6 7
 	"github.com/containerd/platforms"
7 8
 	slsa "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/common"
8 9
 	slsa02 "github.com/in-toto/in-toto-golang/in_toto/slsa_provenance/v0.2"
9 10
 	provenancetypes "github.com/moby/buildkit/solver/llbsolver/provenance/types"
11
+	"github.com/moby/buildkit/util/gitutil"
10 12
 	"github.com/moby/buildkit/util/purl"
11 13
 	"github.com/moby/buildkit/util/urlutil"
12 14
 	"github.com/package-url/packageurl-go"
... ...
@@ -40,10 +42,8 @@ func slsaMaterials(srcs provenancetypes.Sources) ([]slsa.ProvenanceMaterial, err
40 40
 
41 41
 	for _, s := range srcs.Git {
42 42
 		out = append(out, slsa.ProvenanceMaterial{
43
-			URI: s.URL,
44
-			Digest: slsa.DigestSet{
45
-				"sha1": s.Commit,
46
-			},
43
+			URI:    s.URL,
44
+			Digest: digestSetForCommit(s.Commit),
47 45
 		})
48 46
 	}
49 47
 
... ...
@@ -59,14 +59,51 @@ func slsaMaterials(srcs provenancetypes.Sources) ([]slsa.ProvenanceMaterial, err
59 59
 	return out, nil
60 60
 }
61 61
 
62
+func digestSetForCommit(commit string) slsa.DigestSet {
63
+	dset := slsa.DigestSet{}
64
+	if len(commit) == 64 {
65
+		dset["sha256"] = commit
66
+	} else {
67
+		dset["sha1"] = commit
68
+	}
69
+	return dset
70
+}
71
+
62 72
 func findMaterial(srcs provenancetypes.Sources, uri string) (*slsa.ProvenanceMaterial, bool) {
73
+	// Git URLs in querystring format or subdir need to be converted to fragment format with only ref
74
+	gitRef, err := gitutil.ParseURL(uri)
75
+	if err == nil && gitRef != nil {
76
+		u := gitRef.Remote
77
+		var ref string
78
+		if gitRef.Opts != nil {
79
+			ref = gitRef.Opts.Ref
80
+		}
81
+		if len(gitRef.Query) > 0 {
82
+			for k, v := range gitRef.Query {
83
+				if len(v) == 0 {
84
+					continue
85
+				}
86
+				switch k {
87
+				case "ref":
88
+					ref = v[0]
89
+				case "branch":
90
+					ref = "refs/heads/" + v[0]
91
+				case "tag":
92
+					ref = "refs/tags/" + v[0]
93
+				}
94
+			}
95
+		}
96
+		if ref != "" {
97
+			u += "#" + ref
98
+		}
99
+		uri = u
100
+	}
101
+
63 102
 	for _, s := range srcs.Git {
64 103
 		if s.URL == uri {
65 104
 			return &slsa.ProvenanceMaterial{
66
-				URI: s.URL,
67
-				Digest: slsa.DigestSet{
68
-					"sha1": s.Commit,
69
-				},
105
+				URI:    s.URL,
106
+				Digest: digestSetForCommit(s.Commit),
70 107
 			}, true
71 108
 		}
72 109
 	}
... ...
@@ -90,12 +127,16 @@ func NewPredicate(c *Capture) (*provenancetypes.ProvenancePredicateSLSA02, error
90 90
 	}
91 91
 	inv := provenancetypes.ProvenanceInvocationSLSA02{}
92 92
 
93
+	args := maps.Clone(c.Args)
94
+
93 95
 	contextKey := "context"
94
-	if v, ok := c.Args["contextkey"]; ok && v != "" {
96
+	if v, ok := args["contextkey"]; ok && v != "" {
95 97
 		contextKey = v
98
+	} else if v, ok := c.Args["input:context"]; ok && v != "" {
99
+		contextKey = "input:context"
96 100
 	}
97 101
 
98
-	if v, ok := c.Args[contextKey]; ok && v != "" {
102
+	if v, ok := args[contextKey]; ok && v != "" {
99 103
 		if m, ok := findMaterial(c.Sources, v); ok {
100 104
 			inv.ConfigSource.URI = m.URI
101 105
 			inv.ConfigSource.Digest = m.Digest
... ...
@@ -103,21 +144,21 @@ func NewPredicate(c *Capture) (*provenancetypes.ProvenancePredicateSLSA02, error
103 103
 			inv.ConfigSource.URI = v
104 104
 		}
105 105
 		inv.ConfigSource.URI = urlutil.RedactCredentials(inv.ConfigSource.URI)
106
-		delete(c.Args, contextKey)
106
+		delete(args, contextKey)
107 107
 	}
108 108
 
109
-	if v, ok := c.Args["filename"]; ok && v != "" {
109
+	if v, ok := args["filename"]; ok && v != "" {
110 110
 		inv.ConfigSource.EntryPoint = v
111
-		delete(c.Args, "filename")
111
+		delete(args, "filename")
112 112
 	}
113 113
 
114 114
 	vcs := make(map[string]string)
115
-	for k, v := range c.Args {
115
+	for k, v := range args {
116 116
 		if strings.HasPrefix(k, "vcs:") {
117 117
 			if k == "vcs:source" {
118 118
 				v = urlutil.RedactCredentials(v)
119 119
 			}
120
-			delete(c.Args, k)
120
+			delete(args, k)
121 121
 			if v != "" {
122 122
 				vcs[strings.TrimPrefix(k, "vcs:")] = v
123 123
 			}
... ...
@@ -127,7 +168,7 @@ func NewPredicate(c *Capture) (*provenancetypes.ProvenancePredicateSLSA02, error
127 127
 	inv.Environment.Platform = platforms.Format(platforms.Normalize(platforms.DefaultSpec()))
128 128
 
129 129
 	inv.Parameters.Frontend = c.Frontend
130
-	inv.Parameters.Args = c.Args
130
+	inv.Parameters.Args = args
131 131
 
132 132
 	for _, s := range c.Secrets {
133 133
 		inv.Parameters.Secrets = append(inv.Parameters.Secrets, &provenancetypes.Secret{
... ...
@@ -103,33 +103,33 @@ func (ps *ProvenanceSLSA) Validate() error {
103 103
 
104 104
 type ProvenancePredicateSLSA02 struct {
105 105
 	slsa02.ProvenancePredicate
106
-	Invocation  ProvenanceInvocationSLSA02 `json:"invocation,omitempty"`
106
+	Invocation  ProvenanceInvocationSLSA02 `json:"invocation"`
107 107
 	BuildConfig *BuildConfig               `json:"buildConfig,omitempty"`
108 108
 	Metadata    *ProvenanceMetadataSLSA02  `json:"metadata,omitempty"`
109 109
 }
110 110
 
111 111
 type ProvenanceInvocationSLSA02 struct {
112
-	ConfigSource slsa02.ConfigSource `json:"configSource,omitempty"`
113
-	Parameters   Parameters          `json:"parameters,omitempty"`
114
-	Environment  Environment         `json:"environment,omitempty"`
112
+	ConfigSource slsa02.ConfigSource `json:"configSource"`
113
+	Parameters   Parameters          `json:"parameters"`
114
+	Environment  Environment         `json:"environment"`
115 115
 }
116 116
 
117 117
 type ProvenanceMetadataSLSA02 struct {
118 118
 	slsa02.ProvenanceMetadata
119
-	BuildKitMetadata BuildKitMetadata `json:"https://mobyproject.org/buildkit@v1#metadata,omitempty"`
119
+	BuildKitMetadata BuildKitMetadata `json:"https://mobyproject.org/buildkit@v1#metadata"`
120 120
 	Hermetic         bool             `json:"https://mobyproject.org/buildkit@v1#hermetic,omitempty"`
121 121
 }
122 122
 
123 123
 type ProvenancePredicateSLSA1 struct {
124 124
 	slsa1.ProvenancePredicate
125
-	BuildDefinition ProvenanceBuildDefinitionSLSA1 `json:"buildDefinition,omitempty"`
126
-	RunDetails      ProvenanceRunDetailsSLSA1      `json:"runDetails,omitempty"`
125
+	BuildDefinition ProvenanceBuildDefinitionSLSA1 `json:"buildDefinition"`
126
+	RunDetails      ProvenanceRunDetailsSLSA1      `json:"runDetails"`
127 127
 }
128 128
 
129 129
 type ProvenanceBuildDefinitionSLSA1 struct {
130 130
 	slsa1.ProvenanceBuildDefinition
131
-	ExternalParameters ProvenanceExternalParametersSLSA1 `json:"externalParameters,omitempty"`
132
-	InternalParameters ProvenanceInternalParametersSLSA1 `json:"internalParameters,omitempty"`
131
+	ExternalParameters ProvenanceExternalParametersSLSA1 `json:"externalParameters"`
132
+	InternalParameters ProvenanceInternalParametersSLSA1 `json:"internalParameters"`
133 133
 }
134 134
 
135 135
 type ProvenanceRunDetailsSLSA1 struct {
... ...
@@ -138,8 +138,8 @@ type ProvenanceRunDetailsSLSA1 struct {
138 138
 }
139 139
 
140 140
 type ProvenanceExternalParametersSLSA1 struct {
141
-	ConfigSource ProvenanceConfigSourceSLSA1 `json:"configSource,omitempty"`
142
-	Request      Parameters                  `json:"request,omitempty"`
141
+	ConfigSource ProvenanceConfigSourceSLSA1 `json:"configSource"`
142
+	Request      Parameters                  `json:"request"`
143 143
 }
144 144
 
145 145
 type ProvenanceConfigSourceSLSA1 struct {
... ...
@@ -151,13 +151,14 @@ type ProvenanceConfigSourceSLSA1 struct {
151 151
 type ProvenanceInternalParametersSLSA1 struct {
152 152
 	BuildConfig     *BuildConfig `json:"buildConfig,omitempty"`
153 153
 	BuilderPlatform string       `json:"builderPlatform"`
154
+	ProvenanceCustomEnv
154 155
 }
155 156
 
156 157
 type ProvenanceMetadataSLSA1 struct {
157 158
 	slsa1.BuildMetadata
158
-	BuildKitMetadata BuildKitMetadata `json:"buildkit_metadata,omitempty"`
159
+	BuildKitMetadata BuildKitMetadata `json:"buildkit_metadata"`
159 160
 	Hermetic         bool             `json:"buildkit_hermetic,omitempty"`
160
-	Completeness     BuildKitComplete `json:"buildkit_completeness,omitempty"`
161
+	Completeness     BuildKitComplete `json:"buildkit_completeness"`
161 162
 	Reproducible     bool             `json:"buildkit_reproducible,omitempty"`
162 163
 }
163 164
 
... ...
@@ -173,6 +174,7 @@ type Parameters struct {
173 173
 
174 174
 type Environment struct {
175 175
 	Platform string `json:"platform"`
176
+	ProvenanceCustomEnv
176 177
 }
177 178
 
178 179
 type BuildKitMetadata struct {
... ...
@@ -187,6 +189,8 @@ type BuildKitComplete struct {
187 187
 	ResolvedDependencies bool `json:"resolvedDependencies"`
188 188
 }
189 189
 
190
+type ProvenanceCustomEnv map[string]any
191
+
190 192
 // ConvertToSLSA02 converts to a SLSA v0.2 provenance predicate.
191 193
 func (p *ProvenancePredicateSLSA1) ConvertToSLSA02() *ProvenancePredicateSLSA02 {
192 194
 	var materials []slsa02.ProvenanceMaterial
... ...
@@ -232,7 +236,8 @@ func (p *ProvenancePredicateSLSA1) ConvertToSLSA02() *ProvenancePredicateSLSA02
232 232
 			},
233 233
 			Parameters: p.BuildDefinition.ExternalParameters.Request,
234 234
 			Environment: Environment{
235
-				Platform: p.BuildDefinition.InternalParameters.BuilderPlatform,
235
+				Platform:            p.BuildDefinition.InternalParameters.BuilderPlatform,
236
+				ProvenanceCustomEnv: p.BuildDefinition.InternalParameters.ProvenanceCustomEnv,
236 237
 			},
237 238
 		},
238 239
 		BuildConfig: p.BuildDefinition.InternalParameters.BuildConfig,
... ...
@@ -264,8 +269,9 @@ func (p *ProvenancePredicateSLSA02) ConvertToSLSA1() *ProvenancePredicateSLSA1 {
264 264
 			Request: p.Invocation.Parameters,
265 265
 		},
266 266
 		InternalParameters: ProvenanceInternalParametersSLSA1{
267
-			BuildConfig:     p.BuildConfig,
268
-			BuilderPlatform: p.Invocation.Environment.Platform,
267
+			BuildConfig:         p.BuildConfig,
268
+			BuilderPlatform:     p.Invocation.Environment.Platform,
269
+			ProvenanceCustomEnv: p.Invocation.Environment.ProvenanceCustomEnv,
269 270
 		},
270 271
 	}
271 272
 
... ...
@@ -82,6 +82,7 @@ type Opt struct {
82 82
 	WorkerController *worker.Controller
83 83
 	HistoryQueue     *HistoryQueue
84 84
 	ResourceMonitor  *resources.Monitor
85
+	ProvenanceEnv    map[string]any
85 86
 }
86 87
 
87 88
 type Solver struct {
... ...
@@ -96,6 +97,7 @@ type Solver struct {
96 96
 	entitlements              []string
97 97
 	history                   *HistoryQueue
98 98
 	sysSampler                *resources.Sampler[*resourcestypes.SysSample]
99
+	provenanceEnv             map[string]any
99 100
 }
100 101
 
101 102
 // Processor defines a processing function to be applied after solving, but
... ...
@@ -103,6 +105,18 @@ type Solver struct {
103 103
 type Processor func(ctx context.Context, result *Result, s *Solver, j *solver.Job, usage *resources.SysSampler) (*Result, error)
104 104
 
105 105
 func New(opt Opt) (*Solver, error) {
106
+	// buildConfig,builderPlatform,platform are not allowd
107
+	forbiddenKeys := map[string]struct{}{
108
+		"buildConfig":     {},
109
+		"builderPlatform": {},
110
+		"platform":        {},
111
+	}
112
+	for k := range opt.ProvenanceEnv {
113
+		if _, ok := forbiddenKeys[k]; ok {
114
+			return nil, errors.Errorf("key %q is builtin and not allowed to be modified in provenance config", k)
115
+		}
116
+	}
117
+
106 118
 	s := &Solver{
107 119
 		workerController:          opt.WorkerController,
108 120
 		resolveWorker:             defaultResolver(opt.WorkerController),
... ...
@@ -113,6 +127,7 @@ func New(opt Opt) (*Solver, error) {
113 113
 		sm:                        opt.SessionManager,
114 114
 		entitlements:              opt.Entitlements,
115 115
 		history:                   opt.HistoryQueue,
116
+		provenanceEnv:             opt.ProvenanceEnv,
116 117
 	}
117 118
 
118 119
 	sampler, err := resources.NewSysSampler()
... ...
@@ -241,7 +256,7 @@ func (s *Solver) recordBuildHistory(ctx context.Context, id string, req frontend
241 241
 			span, ctx := tracing.StartSpan(ctx, fmt.Sprintf("create %s history provenance", name))
242 242
 			defer span.End()
243 243
 
244
-			pc, err := NewProvenanceCreator(ctx2, slsaVersion, cap, res, attrs, j, usage)
244
+			pc, err := NewProvenanceCreator(ctx2, slsaVersion, cap, res, attrs, j, usage, s.provenanceEnv)
245 245
 			if err != nil {
246 246
 				return nil, nil, err
247 247
 			}
... ...
@@ -994,10 +1009,6 @@ func getRefProvenance(ref solver.ResultProxy, br *provenanceBridge) (*provenance
994 994
 		pr.Frontend = br.req.Frontend
995 995
 		pr.Args = provenance.FilterArgs(br.req.FrontendOpt)
996 996
 		// TODO: should also save some output options like compression
997
-
998
-		if len(br.req.FrontendInputs) > 0 {
999
-			pr.IncompleteMaterials = true // not implemented
1000
-		}
1001 997
 	}
1002 998
 
1003 999
 	return pr, nil
... ...
@@ -34,6 +34,7 @@ const AttrImageResolveModeForcePull = "pull"
34 34
 const AttrImageResolveModePreferLocal = "local"
35 35
 const AttrImageRecordType = "image.recordtype"
36 36
 const AttrImageLayerLimit = "image.layerlimit"
37
+const AttrImageChecksum = "image.checksum"
37 38
 
38 39
 const AttrOCILayoutSessionID = "oci.session"
39 40
 const AttrOCILayoutStoreID = "oci.store"
... ...
@@ -12,6 +12,7 @@ const (
12 12
 	CapSourceImage            apicaps.CapID = "source.image"
13 13
 	CapSourceImageResolveMode apicaps.CapID = "source.image.resolvemode"
14 14
 	CapSourceImageLayerLimit  apicaps.CapID = "source.image.layerlimit"
15
+	CapSourceImageChecksum    apicaps.CapID = "source.image.checksum"
15 16
 
16 17
 	CapSourceLocal                apicaps.CapID = "source.local"
17 18
 	CapSourceLocalUnique          apicaps.CapID = "source.local.unique"
... ...
@@ -129,6 +130,12 @@ func init() {
129 129
 	})
130 130
 
131 131
 	Caps.Init(apicaps.Cap{
132
+		ID:      CapSourceImageChecksum,
133
+		Enabled: true,
134
+		Status:  apicaps.CapStatusExperimental,
135
+	})
136
+
137
+	Caps.Init(apicaps.Cap{
132 138
 		ID:      CapSourceLocal,
133 139
 		Enabled: true,
134 140
 		Status:  apicaps.CapStatusExperimental,
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/solver/pb/ops.proto
6 6
 
... ...
@@ -124,20 +124,29 @@ type CacheExporter interface {
124 124
 
125 125
 // CacheExporterTarget defines object capable of receiving exports
126 126
 type CacheExporterTarget interface {
127
-	// Add creates a new object record that we can then add results to and
128
-	// connect to other records.
129
-	Add(dgst digest.Digest) CacheExporterRecord
130
-
131
-	// Visit marks a target as having been visited.
132
-	Visit(target any)
133
-	// Vistited returns true if a target has previously been marked as visited.
134
-	Visited(target any) bool
127
+	Add(dgst digest.Digest, deps [][]CacheLink, results []CacheExportResult) (CacheExporterRecord, bool, error)
135 128
 }
136 129
 
137
-// CacheExporterRecord is a single object being exported
130
+// opaque interface
138 131
 type CacheExporterRecord interface {
139
-	AddResult(vtx digest.Digest, index int, createdAt time.Time, result *Remote)
140
-	LinkFrom(src CacheExporterRecord, index int, selector string)
132
+	isCacheExporterRecord()
133
+}
134
+
135
+type CacheExporterRecordBase struct {
136
+}
137
+
138
+func (c *CacheExporterRecordBase) isCacheExporterRecord() {}
139
+
140
+type CacheLink struct {
141
+	Src      CacheExporterRecord
142
+	Selector string
143
+}
144
+
145
+type CacheExportResult struct {
146
+	CreatedAt  time.Time
147
+	Result     *Remote
148
+	EdgeVertex digest.Digest
149
+	EdgeIndex  Index
141 150
 }
142 151
 
143 152
 // Remote is a descriptor or a list of stacked descriptors that can be pulled
... ...
@@ -148,15 +157,6 @@ type Remote struct {
148 148
 	Provider    content.InfoReaderProvider
149 149
 }
150 150
 
151
-// CacheLink is a link between two cache records
152
-type CacheLink struct {
153
-	Source   digest.Digest `json:",omitempty"`
154
-	Input    Index         `json:",omitempty"`
155
-	Output   Index         `json:",omitempty"`
156
-	Base     digest.Digest `json:",omitempty"`
157
-	Selector digest.Digest `json:",omitempty"`
158
-}
159
-
160 151
 type ReleaseFunc func()
161 152
 
162 153
 // Op defines how the solver can evaluate the properties of a vertex operation.
... ...
@@ -19,6 +19,7 @@ type ImageIdentifier struct {
19 19
 	ResolveMode resolver.ResolveMode
20 20
 	RecordType  client.UsageRecordType
21 21
 	LayerLimit  *int
22
+	Checksum    digest.Digest
22 23
 }
23 24
 
24 25
 func NewImageIdentifier(str string) (*ImageIdentifier, error) {
... ...
@@ -46,6 +46,7 @@ type puller struct {
46 46
 	Ref            string
47 47
 	SessionManager *session.Manager
48 48
 	layerLimit     *int
49
+	checksum       digest.Digest
49 50
 	vtx            solver.Vertex
50 51
 	ResolverType
51 52
 	store sourceresolver.ResolveImageConfigOptStore
... ...
@@ -130,6 +131,10 @@ func (p *puller) CacheKey(ctx context.Context, g session.Group, index int) (cach
130 130
 			return struct{}{}, err
131 131
 		}
132 132
 
133
+		if p.checksum != "" && p.manifest.MainManifestDesc.Digest != p.checksum {
134
+			return struct{}{}, errors.Errorf("image digest %s for %s does not match expected checksum %s", p.manifest.MainManifestDesc.Digest, p.Ref, p.checksum)
135
+		}
136
+
133 137
 		if ll := p.layerLimit; ll != nil {
134 138
 			if *ll > len(p.manifest.Descriptors) {
135 139
 				return struct{}{}, errors.Errorf("layer limit %d is greater than the number of layers in the image %d", *ll, len(p.manifest.Descriptors))
... ...
@@ -93,6 +93,7 @@ func (is *Source) Resolve(ctx context.Context, id source.Identifier, sm *session
93 93
 		ref        reference.Spec
94 94
 		store      sourceresolver.ResolveImageConfigOptStore
95 95
 		layerLimit *int
96
+		checksum   digest.Digest
96 97
 	)
97 98
 	switch is.ResolverType {
98 99
 	case ResolverTypeRegistry:
... ...
@@ -108,6 +109,7 @@ func (is *Source) Resolve(ctx context.Context, id source.Identifier, sm *session
108 108
 		recordType = imageIdentifier.RecordType
109 109
 		ref = imageIdentifier.Reference
110 110
 		layerLimit = imageIdentifier.LayerLimit
111
+		checksum = imageIdentifier.Checksum
111 112
 	case ResolverTypeOCILayout:
112 113
 		ociIdentifier, ok := id.(*OCIIdentifier)
113 114
 		if !ok {
... ...
@@ -146,6 +148,7 @@ func (is *Source) Resolve(ctx context.Context, id source.Identifier, sm *session
146 146
 		vtx:            vtx,
147 147
 		store:          store,
148 148
 		layerLimit:     layerLimit,
149
+		checksum:       checksum,
149 150
 	}
150 151
 	return p, nil
151 152
 }
... ...
@@ -245,6 +248,12 @@ func (is *Source) registryIdentifier(ref string, attrs map[string]string, platfo
245 245
 				return nil, errors.Errorf("invalid layer limit %s", v)
246 246
 			}
247 247
 			id.LayerLimit = &l
248
+		case pb.AttrImageChecksum:
249
+			dgst, err := digest.Parse(v)
250
+			if err != nil {
251
+				return nil, errors.Wrapf(err, "invalid image checksum %s", v)
252
+			}
253
+			id.Checksum = dgst
248 254
 		}
249 255
 	}
250 256
 
... ...
@@ -105,7 +105,7 @@ func (gs *gitSource) Identifier(scheme, ref string, attrs map[string]string, pla
105 105
 }
106 106
 
107 107
 // needs to be called with repo lock
108
-func (gs *gitSource) mountRemote(ctx context.Context, remote string, authArgs []string, g session.Group) (target string, release func() error, retErr error) {
108
+func (gs *gitSource) mountRemote(ctx context.Context, remote string, authArgs []string, sha256 bool, g session.Group) (target string, release func() error, retErr error) {
109 109
 	sis, err := searchGitRemote(ctx, gs.cache, remote)
110 110
 	if err != nil {
111 111
 		return "", nil, errors.Wrapf(err, "failed to search metadata for %s", urlutil.RedactCredentials(remote))
... ...
@@ -171,7 +171,11 @@ func (gs *gitSource) mountRemote(ctx context.Context, remote string, authArgs []
171 171
 		// implied default to suppress "hint:" output about not having a
172 172
 		// default initial branch name set which otherwise spams unit
173 173
 		// test logs.
174
-		if _, err := git.Run(ctx, "-c", "init.defaultBranch=master", "init", "--bare"); err != nil {
174
+		args := []string{"-c", "init.defaultBranch=master", "init", "--bare"}
175
+		if sha256 {
176
+			args = append(args, "--object-format=sha256")
177
+		}
178
+		if _, err := git.Run(ctx, args...); err != nil {
175 179
 			return "", nil, errors.Wrapf(err, "failed to init repo at %s", dir)
176 180
 		}
177 181
 
... ...
@@ -198,6 +202,7 @@ type gitSourceHandler struct {
198 198
 	*gitSource
199 199
 	src      GitIdentifier
200 200
 	cacheKey string
201
+	sha256   bool
201 202
 	sm       *session.Manager
202 203
 	authArgs []string
203 204
 }
... ...
@@ -376,13 +381,14 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, g session.Group, index
376 376
 	if refCommitFullHash != "" {
377 377
 		cacheKey := gs.shaToCacheKey(refCommitFullHash, ref2)
378 378
 		gs.cacheKey = cacheKey
379
+		gs.sha256 = len(refCommitFullHash) == 64
379 380
 		// gs.src.Checksum is verified when checking out the commit
380 381
 		return cacheKey, refCommitFullHash, nil, true, nil
381 382
 	}
382 383
 
383 384
 	gs.getAuthToken(ctx, g)
384 385
 
385
-	git, cleanup, err := gs.gitCli(ctx, g)
386
+	tmpGit, cleanup, err := gs.emptyGitCli(ctx, g)
386 387
 	if err != nil {
387 388
 		return "", "", nil, false, err
388 389
 	}
... ...
@@ -390,7 +396,7 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, g session.Group, index
390 390
 
391 391
 	ref := gs.src.Ref
392 392
 	if ref == "" {
393
-		ref, err = getDefaultBranch(ctx, git, gs.src.Remote)
393
+		ref, err = getDefaultBranch(ctx, tmpGit, gs.src.Remote)
394 394
 		if err != nil {
395 395
 			return "", "", nil, false, err
396 396
 		}
... ...
@@ -398,7 +404,7 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, g session.Group, index
398 398
 
399 399
 	// TODO: should we assume that remote tag is immutable? add a timer?
400 400
 
401
-	buf, err := git.Run(ctx, "ls-remote", "origin", ref, ref+"^{}")
401
+	buf, err := tmpGit.Run(ctx, "ls-remote", gs.src.Remote, ref, ref+"^{}")
402 402
 	if err != nil {
403 403
 		return "", "", nil, false, errors.Wrapf(err, "failed to fetch remote %s", urlutil.RedactCredentials(remote))
404 404
 	}
... ...
@@ -445,6 +451,7 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, g session.Group, index
445 445
 	}
446 446
 	cacheKey := gs.shaToCacheKey(sha, usedRef)
447 447
 	gs.cacheKey = cacheKey
448
+	gs.sha256 = len(sha) == 64
448 449
 	return cacheKey, sha, nil, true, nil
449 450
 }
450 451
 
... ...
@@ -475,15 +482,18 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
475 475
 	gs.locker.Lock(gs.src.Remote)
476 476
 	defer gs.locker.Unlock(gs.src.Remote)
477 477
 
478
-	git, cleanup, err := gs.gitCli(ctx, g)
478
+	git, cleanup, err := gs.emptyGitCli(ctx, g)
479 479
 	if err != nil {
480 480
 		return nil, err
481 481
 	}
482 482
 	defer cleanup()
483
-	gitDir, err := git.GitDir(ctx)
483
+
484
+	gitDir, unmountGitDir, err := gs.mountRemote(ctx, gs.src.Remote, gs.authArgs, gs.sha256, g)
484 485
 	if err != nil {
485 486
 		return nil, err
486 487
 	}
488
+	defer unmountGitDir()
489
+	git = git.New(gitutil.WithGitDir(gitDir))
487 490
 
488 491
 	ref := gs.src.Ref
489 492
 	if ref == "" {
... ...
@@ -581,7 +591,11 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
581 581
 			return nil, err
582 582
 		}
583 583
 		checkoutGit := git.New(gitutil.WithWorkTree(checkoutDir), gitutil.WithGitDir(checkoutDirGit))
584
-		_, err = checkoutGit.Run(ctx, "-c", "init.defaultBranch=master", "init")
584
+		args := []string{"-c", "init.defaultBranch=master", "init"}
585
+		if gs.sha256 {
586
+			args = append(args, "--object-format=sha256")
587
+		}
588
+		_, err = checkoutGit.Run(ctx, args...)
585 589
 		if err != nil {
586 590
 			return nil, err
587 591
 		}
... ...
@@ -713,7 +727,7 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
713 713
 	return snap, nil
714 714
 }
715 715
 
716
-func (gs *gitSourceHandler) gitCli(ctx context.Context, g session.Group, opts ...gitutil.Option) (*gitutil.GitCLI, func() error, error) {
716
+func (gs *gitSourceHandler) emptyGitCli(ctx context.Context, g session.Group, opts ...gitutil.Option) (*gitutil.GitCLI, func() error, error) {
717 717
 	var cleanups []func() error
718 718
 	cleanup := func() error {
719 719
 		var err error
... ...
@@ -727,13 +741,6 @@ func (gs *gitSourceHandler) gitCli(ctx context.Context, g session.Group, opts ..
727 727
 	}
728 728
 	var err error
729 729
 
730
-	gitDir, unmountGitDir, err := gs.mountRemote(ctx, gs.src.Remote, gs.authArgs, g)
731
-	if err != nil {
732
-		cleanup()
733
-		return nil, nil, err
734
-	}
735
-	cleanups = append(cleanups, unmountGitDir)
736
-
737 730
 	var sock string
738 731
 	if gs.src.MountSSHSock != "" {
739 732
 		var unmountSock func() error
... ...
@@ -757,7 +764,6 @@ func (gs *gitSourceHandler) gitCli(ctx context.Context, g session.Group, opts ..
757 757
 	}
758 758
 
759 759
 	opts = append([]gitutil.Option{
760
-		gitutil.WithGitDir(gitDir),
761 760
 		gitutil.WithArgs(gs.authArgs...),
762 761
 		gitutil.WithSSHAuthSock(sock),
763 762
 		gitutil.WithSSHKnownHosts(knownHosts),
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/sourcepolicy/pb/policy.proto
6 6
 
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/util/apicaps/pb/caps.proto
6 6
 
... ...
@@ -121,11 +121,11 @@ func (r *Record) LoadSubRecords(loader func(d digest.Digest) (Type, []Frame, err
121 121
 			}
122 122
 		}
123 123
 	case TypeDigestList:
124
-		for _, dgst := range bytes.Split(dt, []byte{0}) {
124
+		for dgst := range bytes.SplitSeq(dt, []byte{0}) {
125 125
 			checksums = append(checksums, string(dgst))
126 126
 		}
127 127
 	case TypeFileList:
128
-		for _, nameChecksumPair := range bytes.Split(dt, []byte{0}) {
128
+		for nameChecksumPair := range bytes.SplitSeq(dt, []byte{0}) {
129 129
 			idx := bytes.LastIndex(nameChecksumPair, []byte("sha256:"))
130 130
 			if idx < 0 {
131 131
 				bklog.L.Warnf("invalid file list entry %q, missing sha256 prefix", nameChecksumPair)
... ...
@@ -1,7 +1,7 @@
1 1
 package gitutil
2 2
 
3 3
 func IsCommitSHA(str string) bool {
4
-	if len(str) != 40 {
4
+	if l := len(str); l != 40 && l != 64 {
5 5
 		return false
6 6
 	}
7 7
 
... ...
@@ -107,6 +107,14 @@ func withDetails(ctx context.Context, s *status.Status, details ...proto.Message
107 107
 	return status.FromProto(p), nil
108 108
 }
109 109
 
110
+// Code returns the gRPC status code for the given error.
111
+// If the error type has a `Code() codes.Code` method, it is used.
112
+// If the error type has a `GRPCStatus() *status.Status` method, its code is used.
113
+// As a fallback:
114
+// Supports `Unwrap() error` and `Unwrap() []error` for wrapped errors.
115
+// When the `Unwrap() []error` returns multiple errors, the first one that
116
+// contains a non-OK code is returned.
117
+// Finally, if the error is a context error, the corresponding code is returned.
110 118
 func Code(err error) codes.Code {
111 119
 	if errdefs.IsInternal(err) {
112 120
 		if errdefs.IsResourceExhausted(err) {
... ...
@@ -127,14 +135,20 @@ func Code(err error) codes.Code {
127 127
 		return se.GRPCStatus().Code()
128 128
 	}
129 129
 
130
-	wrapped, ok := err.(interface {
131
-		Unwrap() error
132
-	})
133
-	if ok {
130
+	if wrapped, ok := err.(singleUnwrapper); ok {
134 131
 		if err := wrapped.Unwrap(); err != nil {
135 132
 			return Code(err)
136 133
 		}
137 134
 	}
135
+
136
+	if wrapped, ok := err.(multiUnwrapper); ok {
137
+		for _, err := range wrapped.Unwrap() {
138
+			if c := Code(err); c != codes.OK && c != codes.Unknown {
139
+				return c
140
+			}
141
+		}
142
+	}
143
+
138 144
 	return status.FromContextError(err).Code()
139 145
 }
140 146
 
... ...
@@ -142,6 +156,10 @@ func WrapCode(err error, code codes.Code) error {
142 142
 	return &withCodeError{error: err, code: code}
143 143
 }
144 144
 
145
+// AsGRPCStatus tries to extract a gRPC status from the error.
146
+// Supports  `Unwrap() error` and `Unwrap() []error` for wrapped errors.
147
+// When the `Unwrap() []error` returns multiple errors, the first one that
148
+// contains a gRPC status is returned.
145 149
 func AsGRPCStatus(err error) (*status.Status, bool) {
146 150
 	if err == nil {
147 151
 		return nil, true
... ...
@@ -152,15 +170,20 @@ func AsGRPCStatus(err error) (*status.Status, bool) {
152 152
 		return se.GRPCStatus(), true
153 153
 	}
154 154
 
155
-	wrapped, ok := err.(interface {
156
-		Unwrap() error
157
-	})
158
-	if ok {
155
+	if wrapped, ok := err.(singleUnwrapper); ok {
159 156
 		if err := wrapped.Unwrap(); err != nil {
160 157
 			return AsGRPCStatus(err)
161 158
 		}
162 159
 	}
163 160
 
161
+	if wrapped, ok := err.(multiUnwrapper); ok {
162
+		for _, err := range wrapped.Unwrap() {
163
+			if st, ok := AsGRPCStatus(err); ok && st != nil {
164
+				return st, true
165
+			}
166
+		}
167
+	}
168
+
164 169
 	return nil, false
165 170
 }
166 171
 
... ...
@@ -252,9 +275,22 @@ func (e *withCodeError) Unwrap() error {
252 252
 
253 253
 func each(err error, fn func(error)) {
254 254
 	fn(err)
255
-	if wrapped, ok := err.(interface {
256
-		Unwrap() error
257
-	}); ok {
258
-		each(wrapped.Unwrap(), fn)
255
+
256
+	switch e := err.(type) { //nolint:errorlint // using errors.Is/As is not appropriate here
257
+	case singleUnwrapper:
258
+		each(e.Unwrap(), fn)
259
+	case multiUnwrapper:
260
+		for _, err := range e.Unwrap() {
261
+			each(err, fn)
262
+		}
263
+	default:
259 264
 	}
260 265
 }
266
+
267
+type singleUnwrapper interface {
268
+	Unwrap() error
269
+}
270
+
271
+type multiUnwrapper interface {
272
+	Unwrap() []error
273
+}
... ...
@@ -453,7 +453,7 @@ func parseScopes(s []string) scopes {
453 453
 			return nil
454 454
 		}
455 455
 		// The scopeStr may have strings that contain multiple scopes separated by a space.
456
-		for _, scope := range strings.Split(scopeStr, " ") {
456
+		for scope := range strings.SplitSeq(scopeStr, " ") {
457 457
 			parts := strings.SplitN(scope, ":", 3)
458 458
 			names := []string{parts[0]}
459 459
 			if len(parts) > 1 {
... ...
@@ -1,6 +1,6 @@
1 1
 // Code generated by protoc-gen-go. DO NOT EDIT.
2 2
 // versions:
3
-// 	protoc-gen-go v1.36.6
3
+// 	protoc-gen-go v1.36.9
4 4
 // 	protoc        v3.11.4
5 5
 // source: github.com/moby/buildkit/util/stack/stack.proto
6 6
 
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"unicode/utf8"
12 12
 
13 13
 	"google.golang.org/protobuf/compiler/protogen"
14
+	"google.golang.org/protobuf/internal/filedesc"
14 15
 	"google.golang.org/protobuf/internal/genid"
15 16
 	"google.golang.org/protobuf/reflect/protoreflect"
16 17
 
... ...
@@ -279,8 +280,7 @@ func isLazy(field *protogen.Field) bool {
279 279
 	}
280 280
 
281 281
 	// Was the field marked as [lazy = true] in the .proto file?
282
-	fopts := field.Desc.Options().(*descriptorpb.FieldOptions)
283
-	return fopts.GetLazy()
282
+	return field.Desc.(interface{ IsLazy() bool }).IsLazy()
284 283
 }
285 284
 
286 285
 // opaqueGenGet generates a Get method for a field.
... ...
@@ -573,16 +573,8 @@ func usePresence(message *messageInfo, field *protogen.Field) bool {
573 573
 	if !message.isOpaque() {
574 574
 		return false
575 575
 	}
576
-	return opaqueFieldNeedsPresenceArray(message, field)
577
-}
578
-
579
-func opaqueFieldNeedsPresenceArray(message *messageInfo, field *protogen.Field) bool {
580
-	// Non optional fields need presence if truly lazy field, i.e. are message fields.
581
-	if isLazy(field) {
582
-		return true
583
-	}
584
-	isNotOneof := field.Desc.ContainingOneof() == nil || field.Desc.ContainingOneof().IsSynthetic()
585
-	return field.Desc.HasPresence() && field.Message == nil && isNotOneof
576
+	usePresence, _ := filedesc.UsePresenceForField(field.Desc)
577
+	return usePresence
586 578
 }
587 579
 
588 580
 // opaqueGenHas generates a Has method for a field.
... ...
@@ -832,7 +824,7 @@ func opaqueNeedsPresenceArray(message *messageInfo) bool {
832 832
 		return false
833 833
 	}
834 834
 	for _, field := range message.Fields {
835
-		if opaqueFieldNeedsPresenceArray(message, field) {
835
+		if usePresence, _ := filedesc.UsePresenceForField(field.Desc); usePresence {
836 836
 			return true
837 837
 		}
838 838
 	}
... ...
@@ -371,7 +371,31 @@ func ConsumeVarint(b []byte) (v uint64, n int) {
371 371
 func SizeVarint(v uint64) int {
372 372
 	// This computes 1 + (bits.Len64(v)-1)/7.
373 373
 	// 9/64 is a good enough approximation of 1/7
374
-	return int(9*uint32(bits.Len64(v))+64) / 64
374
+	//
375
+	// The Go compiler can translate the bits.LeadingZeros64 call into the LZCNT
376
+	// instruction, which is very fast on CPUs from the last few years. The
377
+	// specific way of expressing the calculation matches C++ Protobuf, see
378
+	// https://godbolt.org/z/4P3h53oM4 for the C++ code and how gcc/clang
379
+	// optimize that function for GOAMD64=v1 and GOAMD64=v3 (-march=haswell).
380
+
381
+	// By OR'ing v with 1, we guarantee that v is never 0, without changing the
382
+	// result of SizeVarint. LZCNT is not defined for 0, meaning the compiler
383
+	// needs to add extra instructions to handle that case.
384
+	//
385
+	// The Go compiler currently (go1.24.4) does not make use of this knowledge.
386
+	// This opportunity (removing the XOR instruction, which handles the 0 case)
387
+	// results in a small (1%) performance win across CPU architectures.
388
+	//
389
+	// Independently of avoiding the 0 case, we need the v |= 1 line because
390
+	// it allows the Go compiler to eliminate an extra XCHGL barrier.
391
+	v |= 1
392
+
393
+	// It would be clearer to write log2value := 63 - uint32(...), but
394
+	// writing uint32(...) ^ 63 is much more efficient (-14% ARM, -20% Intel).
395
+	// Proof of identity for our value range [0..63]:
396
+	// https://go.dev/play/p/Pdn9hEWYakX
397
+	log2value := uint32(bits.LeadingZeros64(v)) ^ 63
398
+	return int((log2value*9 + (64 + 9)) / 64)
375 399
 }
376 400
 
377 401
 // AppendFixed32 appends v to b as a little-endian uint32.
378 402
Binary files a/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb and b/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb differ
... ...
@@ -9,7 +9,7 @@ import "google.golang.org/protobuf/types/descriptorpb"
9 9
 
10 10
 const (
11 11
 	Minimum = descriptorpb.Edition_EDITION_PROTO2
12
-	Maximum = descriptorpb.Edition_EDITION_2023
12
+	Maximum = descriptorpb.Edition_EDITION_2024
13 13
 
14 14
 	// MaximumKnown is the maximum edition that is known to Go Protobuf, but not
15 15
 	// declared as supported. In other words: end users cannot use it, but
... ...
@@ -13,8 +13,10 @@ import (
13 13
 	"google.golang.org/protobuf/reflect/protoreflect"
14 14
 )
15 15
 
16
-var defaultsCache = make(map[Edition]EditionFeatures)
17
-var defaultsKeys = []Edition{}
16
+var (
17
+	defaultsCache = make(map[Edition]EditionFeatures)
18
+	defaultsKeys  = []Edition{}
19
+)
18 20
 
19 21
 func init() {
20 22
 	unmarshalEditionDefaults(editiondefaults.Defaults)
... ...
@@ -41,7 +43,7 @@ func unmarshalGoFeature(b []byte, parent EditionFeatures) EditionFeatures {
41 41
 			b = b[m:]
42 42
 			parent.StripEnumPrefix = int(v)
43 43
 		default:
44
-			panic(fmt.Sprintf("unkown field number %d while unmarshalling GoFeatures", num))
44
+			panic(fmt.Sprintf("unknown field number %d while unmarshalling GoFeatures", num))
45 45
 		}
46 46
 	}
47 47
 	return parent
... ...
@@ -72,8 +74,11 @@ func unmarshalFeatureSet(b []byte, parent EditionFeatures) EditionFeatures {
72 72
 			case genid.FeatureSet_EnforceNamingStyle_field_number:
73 73
 				// EnforceNamingStyle is enforced in protoc, languages other than C++
74 74
 				// are not supposed to do anything with this feature.
75
+			case genid.FeatureSet_DefaultSymbolVisibility_field_number:
76
+				// DefaultSymbolVisibility is enforced in protoc, runtimes should not
77
+				// inspect this value.
75 78
 			default:
76
-				panic(fmt.Sprintf("unkown field number %d while unmarshalling FeatureSet", num))
79
+				panic(fmt.Sprintf("unknown field number %d while unmarshalling FeatureSet", num))
77 80
 			}
78 81
 		case protowire.BytesType:
79 82
 			v, m := protowire.ConsumeBytes(b)
... ...
@@ -147,7 +152,7 @@ func unmarshalEditionDefaults(b []byte) {
147 147
 			_, m := protowire.ConsumeVarint(b)
148 148
 			b = b[m:]
149 149
 		default:
150
-			panic(fmt.Sprintf("unkown field number %d while unmarshalling EditionDefault", num))
150
+			panic(fmt.Sprintf("unknown field number %d while unmarshalling EditionDefault", num))
151 151
 		}
152 152
 	}
153 153
 }
154 154
new file mode 100644
... ...
@@ -0,0 +1,33 @@
0
+// Copyright 2025 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package filedesc
5
+
6
+import "google.golang.org/protobuf/reflect/protoreflect"
7
+
8
+// UsePresenceForField reports whether the presence bitmap should be used for
9
+// the specified field.
10
+func UsePresenceForField(fd protoreflect.FieldDescriptor) (usePresence, canBeLazy bool) {
11
+	switch {
12
+	case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
13
+		// Oneof fields never use the presence bitmap.
14
+		//
15
+		// Synthetic oneofs are an exception: Those are used to implement proto3
16
+		// optional fields and hence should follow non-oneof field semantics.
17
+		return false, false
18
+
19
+	case fd.IsMap():
20
+		// Map-typed fields never use the presence bitmap.
21
+		return false, false
22
+
23
+	case fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind:
24
+		// Lazy fields always use the presence bitmap (only messages can be lazy).
25
+		isLazy := fd.(interface{ IsLazy() bool }).IsLazy()
26
+		return isLazy, isLazy
27
+
28
+	default:
29
+		// If the field has presence, use the presence bitmap.
30
+		return fd.HasPresence(), false
31
+	}
32
+}
... ...
@@ -27,6 +27,7 @@ const (
27 27
 	Api_SourceContext_field_name protoreflect.Name = "source_context"
28 28
 	Api_Mixins_field_name        protoreflect.Name = "mixins"
29 29
 	Api_Syntax_field_name        protoreflect.Name = "syntax"
30
+	Api_Edition_field_name       protoreflect.Name = "edition"
30 31
 
31 32
 	Api_Name_field_fullname          protoreflect.FullName = "google.protobuf.Api.name"
32 33
 	Api_Methods_field_fullname       protoreflect.FullName = "google.protobuf.Api.methods"
... ...
@@ -35,6 +36,7 @@ const (
35 35
 	Api_SourceContext_field_fullname protoreflect.FullName = "google.protobuf.Api.source_context"
36 36
 	Api_Mixins_field_fullname        protoreflect.FullName = "google.protobuf.Api.mixins"
37 37
 	Api_Syntax_field_fullname        protoreflect.FullName = "google.protobuf.Api.syntax"
38
+	Api_Edition_field_fullname       protoreflect.FullName = "google.protobuf.Api.edition"
38 39
 )
39 40
 
40 41
 // Field numbers for google.protobuf.Api.
... ...
@@ -46,6 +48,7 @@ const (
46 46
 	Api_SourceContext_field_number protoreflect.FieldNumber = 5
47 47
 	Api_Mixins_field_number        protoreflect.FieldNumber = 6
48 48
 	Api_Syntax_field_number        protoreflect.FieldNumber = 7
49
+	Api_Edition_field_number       protoreflect.FieldNumber = 8
49 50
 )
50 51
 
51 52
 // Names for google.protobuf.Method.
... ...
@@ -63,6 +66,7 @@ const (
63 63
 	Method_ResponseStreaming_field_name protoreflect.Name = "response_streaming"
64 64
 	Method_Options_field_name           protoreflect.Name = "options"
65 65
 	Method_Syntax_field_name            protoreflect.Name = "syntax"
66
+	Method_Edition_field_name           protoreflect.Name = "edition"
66 67
 
67 68
 	Method_Name_field_fullname              protoreflect.FullName = "google.protobuf.Method.name"
68 69
 	Method_RequestTypeUrl_field_fullname    protoreflect.FullName = "google.protobuf.Method.request_type_url"
... ...
@@ -71,6 +75,7 @@ const (
71 71
 	Method_ResponseStreaming_field_fullname protoreflect.FullName = "google.protobuf.Method.response_streaming"
72 72
 	Method_Options_field_fullname           protoreflect.FullName = "google.protobuf.Method.options"
73 73
 	Method_Syntax_field_fullname            protoreflect.FullName = "google.protobuf.Method.syntax"
74
+	Method_Edition_field_fullname           protoreflect.FullName = "google.protobuf.Method.edition"
74 75
 )
75 76
 
76 77
 // Field numbers for google.protobuf.Method.
... ...
@@ -82,6 +87,7 @@ const (
82 82
 	Method_ResponseStreaming_field_number protoreflect.FieldNumber = 5
83 83
 	Method_Options_field_number           protoreflect.FieldNumber = 6
84 84
 	Method_Syntax_field_number            protoreflect.FieldNumber = 7
85
+	Method_Edition_field_number           protoreflect.FieldNumber = 8
85 86
 )
86 87
 
87 88
 // Names for google.protobuf.Mixin.
... ...
@@ -34,6 +34,19 @@ const (
34 34
 	Edition_EDITION_MAX_enum_value             = 2147483647
35 35
 )
36 36
 
37
+// Full and short names for google.protobuf.SymbolVisibility.
38
+const (
39
+	SymbolVisibility_enum_fullname = "google.protobuf.SymbolVisibility"
40
+	SymbolVisibility_enum_name     = "SymbolVisibility"
41
+)
42
+
43
+// Enum values for google.protobuf.SymbolVisibility.
44
+const (
45
+	SymbolVisibility_VISIBILITY_UNSET_enum_value  = 0
46
+	SymbolVisibility_VISIBILITY_LOCAL_enum_value  = 1
47
+	SymbolVisibility_VISIBILITY_EXPORT_enum_value = 2
48
+)
49
+
37 50
 // Names for google.protobuf.FileDescriptorSet.
38 51
 const (
39 52
 	FileDescriptorSet_message_name     protoreflect.Name     = "FileDescriptorSet"
... ...
@@ -65,6 +78,7 @@ const (
65 65
 	FileDescriptorProto_Dependency_field_name       protoreflect.Name = "dependency"
66 66
 	FileDescriptorProto_PublicDependency_field_name protoreflect.Name = "public_dependency"
67 67
 	FileDescriptorProto_WeakDependency_field_name   protoreflect.Name = "weak_dependency"
68
+	FileDescriptorProto_OptionDependency_field_name protoreflect.Name = "option_dependency"
68 69
 	FileDescriptorProto_MessageType_field_name      protoreflect.Name = "message_type"
69 70
 	FileDescriptorProto_EnumType_field_name         protoreflect.Name = "enum_type"
70 71
 	FileDescriptorProto_Service_field_name          protoreflect.Name = "service"
... ...
@@ -79,6 +93,7 @@ const (
79 79
 	FileDescriptorProto_Dependency_field_fullname       protoreflect.FullName = "google.protobuf.FileDescriptorProto.dependency"
80 80
 	FileDescriptorProto_PublicDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.public_dependency"
81 81
 	FileDescriptorProto_WeakDependency_field_fullname   protoreflect.FullName = "google.protobuf.FileDescriptorProto.weak_dependency"
82
+	FileDescriptorProto_OptionDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.option_dependency"
82 83
 	FileDescriptorProto_MessageType_field_fullname      protoreflect.FullName = "google.protobuf.FileDescriptorProto.message_type"
83 84
 	FileDescriptorProto_EnumType_field_fullname         protoreflect.FullName = "google.protobuf.FileDescriptorProto.enum_type"
84 85
 	FileDescriptorProto_Service_field_fullname          protoreflect.FullName = "google.protobuf.FileDescriptorProto.service"
... ...
@@ -96,6 +111,7 @@ const (
96 96
 	FileDescriptorProto_Dependency_field_number       protoreflect.FieldNumber = 3
97 97
 	FileDescriptorProto_PublicDependency_field_number protoreflect.FieldNumber = 10
98 98
 	FileDescriptorProto_WeakDependency_field_number   protoreflect.FieldNumber = 11
99
+	FileDescriptorProto_OptionDependency_field_number protoreflect.FieldNumber = 15
99 100
 	FileDescriptorProto_MessageType_field_number      protoreflect.FieldNumber = 4
100 101
 	FileDescriptorProto_EnumType_field_number         protoreflect.FieldNumber = 5
101 102
 	FileDescriptorProto_Service_field_number          protoreflect.FieldNumber = 6
... ...
@@ -124,6 +140,7 @@ const (
124 124
 	DescriptorProto_Options_field_name        protoreflect.Name = "options"
125 125
 	DescriptorProto_ReservedRange_field_name  protoreflect.Name = "reserved_range"
126 126
 	DescriptorProto_ReservedName_field_name   protoreflect.Name = "reserved_name"
127
+	DescriptorProto_Visibility_field_name     protoreflect.Name = "visibility"
127 128
 
128 129
 	DescriptorProto_Name_field_fullname           protoreflect.FullName = "google.protobuf.DescriptorProto.name"
129 130
 	DescriptorProto_Field_field_fullname          protoreflect.FullName = "google.protobuf.DescriptorProto.field"
... ...
@@ -135,6 +152,7 @@ const (
135 135
 	DescriptorProto_Options_field_fullname        protoreflect.FullName = "google.protobuf.DescriptorProto.options"
136 136
 	DescriptorProto_ReservedRange_field_fullname  protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_range"
137 137
 	DescriptorProto_ReservedName_field_fullname   protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_name"
138
+	DescriptorProto_Visibility_field_fullname     protoreflect.FullName = "google.protobuf.DescriptorProto.visibility"
138 139
 )
139 140
 
140 141
 // Field numbers for google.protobuf.DescriptorProto.
... ...
@@ -149,6 +167,7 @@ const (
149 149
 	DescriptorProto_Options_field_number        protoreflect.FieldNumber = 7
150 150
 	DescriptorProto_ReservedRange_field_number  protoreflect.FieldNumber = 9
151 151
 	DescriptorProto_ReservedName_field_number   protoreflect.FieldNumber = 10
152
+	DescriptorProto_Visibility_field_number     protoreflect.FieldNumber = 11
152 153
 )
153 154
 
154 155
 // Names for google.protobuf.DescriptorProto.ExtensionRange.
... ...
@@ -388,12 +407,14 @@ const (
388 388
 	EnumDescriptorProto_Options_field_name       protoreflect.Name = "options"
389 389
 	EnumDescriptorProto_ReservedRange_field_name protoreflect.Name = "reserved_range"
390 390
 	EnumDescriptorProto_ReservedName_field_name  protoreflect.Name = "reserved_name"
391
+	EnumDescriptorProto_Visibility_field_name    protoreflect.Name = "visibility"
391 392
 
392 393
 	EnumDescriptorProto_Name_field_fullname          protoreflect.FullName = "google.protobuf.EnumDescriptorProto.name"
393 394
 	EnumDescriptorProto_Value_field_fullname         protoreflect.FullName = "google.protobuf.EnumDescriptorProto.value"
394 395
 	EnumDescriptorProto_Options_field_fullname       protoreflect.FullName = "google.protobuf.EnumDescriptorProto.options"
395 396
 	EnumDescriptorProto_ReservedRange_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_range"
396 397
 	EnumDescriptorProto_ReservedName_field_fullname  protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_name"
398
+	EnumDescriptorProto_Visibility_field_fullname    protoreflect.FullName = "google.protobuf.EnumDescriptorProto.visibility"
397 399
 )
398 400
 
399 401
 // Field numbers for google.protobuf.EnumDescriptorProto.
... ...
@@ -403,6 +424,7 @@ const (
403 403
 	EnumDescriptorProto_Options_field_number       protoreflect.FieldNumber = 3
404 404
 	EnumDescriptorProto_ReservedRange_field_number protoreflect.FieldNumber = 4
405 405
 	EnumDescriptorProto_ReservedName_field_number  protoreflect.FieldNumber = 5
406
+	EnumDescriptorProto_Visibility_field_number    protoreflect.FieldNumber = 6
406 407
 )
407 408
 
408 409
 // Names for google.protobuf.EnumDescriptorProto.EnumReservedRange.
... ...
@@ -1008,32 +1030,35 @@ const (
1008 1008
 
1009 1009
 // Field names for google.protobuf.FeatureSet.
1010 1010
 const (
1011
-	FeatureSet_FieldPresence_field_name         protoreflect.Name = "field_presence"
1012
-	FeatureSet_EnumType_field_name              protoreflect.Name = "enum_type"
1013
-	FeatureSet_RepeatedFieldEncoding_field_name protoreflect.Name = "repeated_field_encoding"
1014
-	FeatureSet_Utf8Validation_field_name        protoreflect.Name = "utf8_validation"
1015
-	FeatureSet_MessageEncoding_field_name       protoreflect.Name = "message_encoding"
1016
-	FeatureSet_JsonFormat_field_name            protoreflect.Name = "json_format"
1017
-	FeatureSet_EnforceNamingStyle_field_name    protoreflect.Name = "enforce_naming_style"
1018
-
1019
-	FeatureSet_FieldPresence_field_fullname         protoreflect.FullName = "google.protobuf.FeatureSet.field_presence"
1020
-	FeatureSet_EnumType_field_fullname              protoreflect.FullName = "google.protobuf.FeatureSet.enum_type"
1021
-	FeatureSet_RepeatedFieldEncoding_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.repeated_field_encoding"
1022
-	FeatureSet_Utf8Validation_field_fullname        protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation"
1023
-	FeatureSet_MessageEncoding_field_fullname       protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding"
1024
-	FeatureSet_JsonFormat_field_fullname            protoreflect.FullName = "google.protobuf.FeatureSet.json_format"
1025
-	FeatureSet_EnforceNamingStyle_field_fullname    protoreflect.FullName = "google.protobuf.FeatureSet.enforce_naming_style"
1011
+	FeatureSet_FieldPresence_field_name           protoreflect.Name = "field_presence"
1012
+	FeatureSet_EnumType_field_name                protoreflect.Name = "enum_type"
1013
+	FeatureSet_RepeatedFieldEncoding_field_name   protoreflect.Name = "repeated_field_encoding"
1014
+	FeatureSet_Utf8Validation_field_name          protoreflect.Name = "utf8_validation"
1015
+	FeatureSet_MessageEncoding_field_name         protoreflect.Name = "message_encoding"
1016
+	FeatureSet_JsonFormat_field_name              protoreflect.Name = "json_format"
1017
+	FeatureSet_EnforceNamingStyle_field_name      protoreflect.Name = "enforce_naming_style"
1018
+	FeatureSet_DefaultSymbolVisibility_field_name protoreflect.Name = "default_symbol_visibility"
1019
+
1020
+	FeatureSet_FieldPresence_field_fullname           protoreflect.FullName = "google.protobuf.FeatureSet.field_presence"
1021
+	FeatureSet_EnumType_field_fullname                protoreflect.FullName = "google.protobuf.FeatureSet.enum_type"
1022
+	FeatureSet_RepeatedFieldEncoding_field_fullname   protoreflect.FullName = "google.protobuf.FeatureSet.repeated_field_encoding"
1023
+	FeatureSet_Utf8Validation_field_fullname          protoreflect.FullName = "google.protobuf.FeatureSet.utf8_validation"
1024
+	FeatureSet_MessageEncoding_field_fullname         protoreflect.FullName = "google.protobuf.FeatureSet.message_encoding"
1025
+	FeatureSet_JsonFormat_field_fullname              protoreflect.FullName = "google.protobuf.FeatureSet.json_format"
1026
+	FeatureSet_EnforceNamingStyle_field_fullname      protoreflect.FullName = "google.protobuf.FeatureSet.enforce_naming_style"
1027
+	FeatureSet_DefaultSymbolVisibility_field_fullname protoreflect.FullName = "google.protobuf.FeatureSet.default_symbol_visibility"
1026 1028
 )
1027 1029
 
1028 1030
 // Field numbers for google.protobuf.FeatureSet.
1029 1031
 const (
1030
-	FeatureSet_FieldPresence_field_number         protoreflect.FieldNumber = 1
1031
-	FeatureSet_EnumType_field_number              protoreflect.FieldNumber = 2
1032
-	FeatureSet_RepeatedFieldEncoding_field_number protoreflect.FieldNumber = 3
1033
-	FeatureSet_Utf8Validation_field_number        protoreflect.FieldNumber = 4
1034
-	FeatureSet_MessageEncoding_field_number       protoreflect.FieldNumber = 5
1035
-	FeatureSet_JsonFormat_field_number            protoreflect.FieldNumber = 6
1036
-	FeatureSet_EnforceNamingStyle_field_number    protoreflect.FieldNumber = 7
1032
+	FeatureSet_FieldPresence_field_number           protoreflect.FieldNumber = 1
1033
+	FeatureSet_EnumType_field_number                protoreflect.FieldNumber = 2
1034
+	FeatureSet_RepeatedFieldEncoding_field_number   protoreflect.FieldNumber = 3
1035
+	FeatureSet_Utf8Validation_field_number          protoreflect.FieldNumber = 4
1036
+	FeatureSet_MessageEncoding_field_number         protoreflect.FieldNumber = 5
1037
+	FeatureSet_JsonFormat_field_number              protoreflect.FieldNumber = 6
1038
+	FeatureSet_EnforceNamingStyle_field_number      protoreflect.FieldNumber = 7
1039
+	FeatureSet_DefaultSymbolVisibility_field_number protoreflect.FieldNumber = 8
1037 1040
 )
1038 1041
 
1039 1042
 // Full and short names for google.protobuf.FeatureSet.FieldPresence.
... ...
@@ -1128,6 +1153,27 @@ const (
1128 1128
 	FeatureSet_STYLE_LEGACY_enum_value                 = 2
1129 1129
 )
1130 1130
 
1131
+// Names for google.protobuf.FeatureSet.VisibilityFeature.
1132
+const (
1133
+	FeatureSet_VisibilityFeature_message_name     protoreflect.Name     = "VisibilityFeature"
1134
+	FeatureSet_VisibilityFeature_message_fullname protoreflect.FullName = "google.protobuf.FeatureSet.VisibilityFeature"
1135
+)
1136
+
1137
+// Full and short names for google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility.
1138
+const (
1139
+	FeatureSet_VisibilityFeature_DefaultSymbolVisibility_enum_fullname = "google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility"
1140
+	FeatureSet_VisibilityFeature_DefaultSymbolVisibility_enum_name     = "DefaultSymbolVisibility"
1141
+)
1142
+
1143
+// Enum values for google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility.
1144
+const (
1145
+	FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN_enum_value = 0
1146
+	FeatureSet_VisibilityFeature_EXPORT_ALL_enum_value                        = 1
1147
+	FeatureSet_VisibilityFeature_EXPORT_TOP_LEVEL_enum_value                  = 2
1148
+	FeatureSet_VisibilityFeature_LOCAL_ALL_enum_value                         = 3
1149
+	FeatureSet_VisibilityFeature_STRICT_enum_value                            = 4
1150
+)
1151
+
1131 1152
 // Names for google.protobuf.FeatureSetDefaults.
1132 1153
 const (
1133 1154
 	FeatureSetDefaults_message_name     protoreflect.Name     = "FeatureSetDefaults"
... ...
@@ -11,6 +11,7 @@ import (
11 11
 
12 12
 	"google.golang.org/protobuf/encoding/protowire"
13 13
 	"google.golang.org/protobuf/internal/encoding/messageset"
14
+	"google.golang.org/protobuf/internal/filedesc"
14 15
 	"google.golang.org/protobuf/internal/order"
15 16
 	"google.golang.org/protobuf/reflect/protoreflect"
16 17
 	piface "google.golang.org/protobuf/runtime/protoiface"
... ...
@@ -80,7 +81,7 @@ func (mi *MessageInfo) makeOpaqueCoderMethods(t reflect.Type, si opaqueStructInf
80 80
 		// permit us to skip over definitely-unset fields at marshal time.
81 81
 
82 82
 		var hasPresence bool
83
-		hasPresence, cf.isLazy = usePresenceForField(si, fd)
83
+		hasPresence, cf.isLazy = filedesc.UsePresenceForField(fd)
84 84
 
85 85
 		if hasPresence {
86 86
 			cf.presenceIndex, mi.presenceSize = presenceIndex(mi.Desc, fd)
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"strings"
12 12
 	"sync/atomic"
13 13
 
14
+	"google.golang.org/protobuf/internal/filedesc"
14 15
 	"google.golang.org/protobuf/reflect/protoreflect"
15 16
 )
16 17
 
... ...
@@ -53,7 +54,7 @@ func opaqueInitHook(mi *MessageInfo) bool {
53 53
 		fd := fds.Get(i)
54 54
 		fs := si.fieldsByNumber[fd.Number()]
55 55
 		var fi fieldInfo
56
-		usePresence, _ := usePresenceForField(si, fd)
56
+		usePresence, _ := filedesc.UsePresenceForField(fd)
57 57
 
58 58
 		switch {
59 59
 		case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
... ...
@@ -343,17 +344,15 @@ func (mi *MessageInfo) fieldInfoForMessageListOpaqueNoPresence(si opaqueStructIn
343 343
 			if p.IsNil() {
344 344
 				return false
345 345
 			}
346
-			sp := p.Apply(fieldOffset).AtomicGetPointer()
347
-			if sp.IsNil() {
346
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
347
+			if rv.IsNil() {
348 348
 				return false
349 349
 			}
350
-			rv := sp.AsValueOf(fs.Type.Elem())
351 350
 			return rv.Elem().Len() > 0
352 351
 		},
353 352
 		clear: func(p pointer) {
354
-			sp := p.Apply(fieldOffset).AtomicGetPointer()
355
-			if !sp.IsNil() {
356
-				rv := sp.AsValueOf(fs.Type.Elem())
353
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
354
+			if !rv.IsNil() {
357 355
 				rv.Elem().Set(reflect.Zero(rv.Type().Elem()))
358 356
 			}
359 357
 		},
... ...
@@ -361,11 +360,10 @@ func (mi *MessageInfo) fieldInfoForMessageListOpaqueNoPresence(si opaqueStructIn
361 361
 			if p.IsNil() {
362 362
 				return conv.Zero()
363 363
 			}
364
-			sp := p.Apply(fieldOffset).AtomicGetPointer()
365
-			if sp.IsNil() {
364
+			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
365
+			if rv.IsNil() {
366 366
 				return conv.Zero()
367 367
 			}
368
-			rv := sp.AsValueOf(fs.Type.Elem())
369 368
 			if rv.Elem().Len() == 0 {
370 369
 				return conv.Zero()
371 370
 			}
... ...
@@ -598,30 +596,3 @@ func (mi *MessageInfo) clearPresent(p pointer, index uint32) {
598 598
 func (mi *MessageInfo) present(p pointer, index uint32) bool {
599 599
 	return p.Apply(mi.presenceOffset).PresenceInfo().Present(index)
600 600
 }
601
-
602
-// usePresenceForField implements the somewhat intricate logic of when
603
-// the presence bitmap is used for a field.  The main logic is that a
604
-// field that is optional or that can be lazy will use the presence
605
-// bit, but for proto2, also maps have a presence bit. It also records
606
-// if the field can ever be lazy, which is true if we have a
607
-// lazyOffset and the field is a message or a slice of messages. A
608
-// field that is lazy will always need a presence bit.  Oneofs are not
609
-// lazy and do not use presence, unless they are a synthetic oneof,
610
-// which is a proto3 optional field. For proto3 optionals, we use the
611
-// presence and they can also be lazy when applicable (a message).
612
-func usePresenceForField(si opaqueStructInfo, fd protoreflect.FieldDescriptor) (usePresence, canBeLazy bool) {
613
-	hasLazyField := fd.(interface{ IsLazy() bool }).IsLazy()
614
-
615
-	// Non-oneof scalar fields with explicit field presence use the presence array.
616
-	usesPresenceArray := fd.HasPresence() && fd.Message() == nil && (fd.ContainingOneof() == nil || fd.ContainingOneof().IsSynthetic())
617
-	switch {
618
-	case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic():
619
-		return false, false
620
-	case fd.IsMap():
621
-		return false, false
622
-	case fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind:
623
-		return hasLazyField, hasLazyField
624
-	default:
625
-		return usesPresenceArray || (hasLazyField && fd.HasPresence()), false
626
-	}
627
-}
... ...
@@ -32,9 +32,6 @@ func (p presence) toElem(num uint32) (ret *uint32) {
32 32
 
33 33
 // Present checks for the presence of a specific field number in a presence set.
34 34
 func (p presence) Present(num uint32) bool {
35
-	if p.P == nil {
36
-		return false
37
-	}
38 35
 	return Export{}.Present(p.toElem(num), num)
39 36
 }
40 37
 
... ...
@@ -52,7 +52,7 @@ import (
52 52
 const (
53 53
 	Major      = 1
54 54
 	Minor      = 36
55
-	Patch      = 6
55
+	Patch      = 9
56 56
 	PreRelease = ""
57 57
 )
58 58
 
... ...
@@ -21,6 +21,8 @@ func (p *SourcePath) appendFileDescriptorProto(b []byte) []byte {
21 21
 		b = p.appendRepeatedField(b, "public_dependency", nil)
22 22
 	case 11:
23 23
 		b = p.appendRepeatedField(b, "weak_dependency", nil)
24
+	case 15:
25
+		b = p.appendRepeatedField(b, "option_dependency", nil)
24 26
 	case 4:
25 27
 		b = p.appendRepeatedField(b, "message_type", (*SourcePath).appendDescriptorProto)
26 28
 	case 5:
... ...
@@ -66,6 +68,8 @@ func (p *SourcePath) appendDescriptorProto(b []byte) []byte {
66 66
 		b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendDescriptorProto_ReservedRange)
67 67
 	case 10:
68 68
 		b = p.appendRepeatedField(b, "reserved_name", nil)
69
+	case 11:
70
+		b = p.appendSingularField(b, "visibility", nil)
69 71
 	}
70 72
 	return b
71 73
 }
... ...
@@ -85,6 +89,8 @@ func (p *SourcePath) appendEnumDescriptorProto(b []byte) []byte {
85 85
 		b = p.appendRepeatedField(b, "reserved_range", (*SourcePath).appendEnumDescriptorProto_EnumReservedRange)
86 86
 	case 5:
87 87
 		b = p.appendRepeatedField(b, "reserved_name", nil)
88
+	case 6:
89
+		b = p.appendSingularField(b, "visibility", nil)
88 90
 	}
89 91
 	return b
90 92
 }
... ...
@@ -400,6 +406,8 @@ func (p *SourcePath) appendFeatureSet(b []byte) []byte {
400 400
 		b = p.appendSingularField(b, "json_format", nil)
401 401
 	case 7:
402 402
 		b = p.appendSingularField(b, "enforce_naming_style", nil)
403
+	case 8:
404
+		b = p.appendSingularField(b, "default_symbol_visibility", nil)
403 405
 	}
404 406
 	return b
405 407
 }
... ...
@@ -151,6 +151,70 @@ func (Edition) EnumDescriptor() ([]byte, []int) {
151 151
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{0}
152 152
 }
153 153
 
154
+// Describes the 'visibility' of a symbol with respect to the proto import
155
+// system. Symbols can only be imported when the visibility rules do not prevent
156
+// it (ex: local symbols cannot be imported).  Visibility modifiers can only set
157
+// on `message` and `enum` as they are the only types available to be referenced
158
+// from other files.
159
+type SymbolVisibility int32
160
+
161
+const (
162
+	SymbolVisibility_VISIBILITY_UNSET  SymbolVisibility = 0
163
+	SymbolVisibility_VISIBILITY_LOCAL  SymbolVisibility = 1
164
+	SymbolVisibility_VISIBILITY_EXPORT SymbolVisibility = 2
165
+)
166
+
167
+// Enum value maps for SymbolVisibility.
168
+var (
169
+	SymbolVisibility_name = map[int32]string{
170
+		0: "VISIBILITY_UNSET",
171
+		1: "VISIBILITY_LOCAL",
172
+		2: "VISIBILITY_EXPORT",
173
+	}
174
+	SymbolVisibility_value = map[string]int32{
175
+		"VISIBILITY_UNSET":  0,
176
+		"VISIBILITY_LOCAL":  1,
177
+		"VISIBILITY_EXPORT": 2,
178
+	}
179
+)
180
+
181
+func (x SymbolVisibility) Enum() *SymbolVisibility {
182
+	p := new(SymbolVisibility)
183
+	*p = x
184
+	return p
185
+}
186
+
187
+func (x SymbolVisibility) String() string {
188
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
189
+}
190
+
191
+func (SymbolVisibility) Descriptor() protoreflect.EnumDescriptor {
192
+	return file_google_protobuf_descriptor_proto_enumTypes[1].Descriptor()
193
+}
194
+
195
+func (SymbolVisibility) Type() protoreflect.EnumType {
196
+	return &file_google_protobuf_descriptor_proto_enumTypes[1]
197
+}
198
+
199
+func (x SymbolVisibility) Number() protoreflect.EnumNumber {
200
+	return protoreflect.EnumNumber(x)
201
+}
202
+
203
+// Deprecated: Do not use.
204
+func (x *SymbolVisibility) UnmarshalJSON(b []byte) error {
205
+	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
206
+	if err != nil {
207
+		return err
208
+	}
209
+	*x = SymbolVisibility(num)
210
+	return nil
211
+}
212
+
213
+// Deprecated: Use SymbolVisibility.Descriptor instead.
214
+func (SymbolVisibility) EnumDescriptor() ([]byte, []int) {
215
+	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{1}
216
+}
217
+
154 218
 // The verification state of the extension range.
155 219
 type ExtensionRangeOptions_VerificationState int32
156 220
 
... ...
@@ -183,11 +247,11 @@ func (x ExtensionRangeOptions_VerificationState) String() string {
183 183
 }
184 184
 
185 185
 func (ExtensionRangeOptions_VerificationState) Descriptor() protoreflect.EnumDescriptor {
186
-	return file_google_protobuf_descriptor_proto_enumTypes[1].Descriptor()
186
+	return file_google_protobuf_descriptor_proto_enumTypes[2].Descriptor()
187 187
 }
188 188
 
189 189
 func (ExtensionRangeOptions_VerificationState) Type() protoreflect.EnumType {
190
-	return &file_google_protobuf_descriptor_proto_enumTypes[1]
190
+	return &file_google_protobuf_descriptor_proto_enumTypes[2]
191 191
 }
192 192
 
193 193
 func (x ExtensionRangeOptions_VerificationState) Number() protoreflect.EnumNumber {
... ...
@@ -299,11 +363,11 @@ func (x FieldDescriptorProto_Type) String() string {
299 299
 }
300 300
 
301 301
 func (FieldDescriptorProto_Type) Descriptor() protoreflect.EnumDescriptor {
302
-	return file_google_protobuf_descriptor_proto_enumTypes[2].Descriptor()
302
+	return file_google_protobuf_descriptor_proto_enumTypes[3].Descriptor()
303 303
 }
304 304
 
305 305
 func (FieldDescriptorProto_Type) Type() protoreflect.EnumType {
306
-	return &file_google_protobuf_descriptor_proto_enumTypes[2]
306
+	return &file_google_protobuf_descriptor_proto_enumTypes[3]
307 307
 }
308 308
 
309 309
 func (x FieldDescriptorProto_Type) Number() protoreflect.EnumNumber {
... ...
@@ -362,11 +426,11 @@ func (x FieldDescriptorProto_Label) String() string {
362 362
 }
363 363
 
364 364
 func (FieldDescriptorProto_Label) Descriptor() protoreflect.EnumDescriptor {
365
-	return file_google_protobuf_descriptor_proto_enumTypes[3].Descriptor()
365
+	return file_google_protobuf_descriptor_proto_enumTypes[4].Descriptor()
366 366
 }
367 367
 
368 368
 func (FieldDescriptorProto_Label) Type() protoreflect.EnumType {
369
-	return &file_google_protobuf_descriptor_proto_enumTypes[3]
369
+	return &file_google_protobuf_descriptor_proto_enumTypes[4]
370 370
 }
371 371
 
372 372
 func (x FieldDescriptorProto_Label) Number() protoreflect.EnumNumber {
... ...
@@ -423,11 +487,11 @@ func (x FileOptions_OptimizeMode) String() string {
423 423
 }
424 424
 
425 425
 func (FileOptions_OptimizeMode) Descriptor() protoreflect.EnumDescriptor {
426
-	return file_google_protobuf_descriptor_proto_enumTypes[4].Descriptor()
426
+	return file_google_protobuf_descriptor_proto_enumTypes[5].Descriptor()
427 427
 }
428 428
 
429 429
 func (FileOptions_OptimizeMode) Type() protoreflect.EnumType {
430
-	return &file_google_protobuf_descriptor_proto_enumTypes[4]
430
+	return &file_google_protobuf_descriptor_proto_enumTypes[5]
431 431
 }
432 432
 
433 433
 func (x FileOptions_OptimizeMode) Number() protoreflect.EnumNumber {
... ...
@@ -489,11 +553,11 @@ func (x FieldOptions_CType) String() string {
489 489
 }
490 490
 
491 491
 func (FieldOptions_CType) Descriptor() protoreflect.EnumDescriptor {
492
-	return file_google_protobuf_descriptor_proto_enumTypes[5].Descriptor()
492
+	return file_google_protobuf_descriptor_proto_enumTypes[6].Descriptor()
493 493
 }
494 494
 
495 495
 func (FieldOptions_CType) Type() protoreflect.EnumType {
496
-	return &file_google_protobuf_descriptor_proto_enumTypes[5]
496
+	return &file_google_protobuf_descriptor_proto_enumTypes[6]
497 497
 }
498 498
 
499 499
 func (x FieldOptions_CType) Number() protoreflect.EnumNumber {
... ...
@@ -551,11 +615,11 @@ func (x FieldOptions_JSType) String() string {
551 551
 }
552 552
 
553 553
 func (FieldOptions_JSType) Descriptor() protoreflect.EnumDescriptor {
554
-	return file_google_protobuf_descriptor_proto_enumTypes[6].Descriptor()
554
+	return file_google_protobuf_descriptor_proto_enumTypes[7].Descriptor()
555 555
 }
556 556
 
557 557
 func (FieldOptions_JSType) Type() protoreflect.EnumType {
558
-	return &file_google_protobuf_descriptor_proto_enumTypes[6]
558
+	return &file_google_protobuf_descriptor_proto_enumTypes[7]
559 559
 }
560 560
 
561 561
 func (x FieldOptions_JSType) Number() protoreflect.EnumNumber {
... ...
@@ -611,11 +675,11 @@ func (x FieldOptions_OptionRetention) String() string {
611 611
 }
612 612
 
613 613
 func (FieldOptions_OptionRetention) Descriptor() protoreflect.EnumDescriptor {
614
-	return file_google_protobuf_descriptor_proto_enumTypes[7].Descriptor()
614
+	return file_google_protobuf_descriptor_proto_enumTypes[8].Descriptor()
615 615
 }
616 616
 
617 617
 func (FieldOptions_OptionRetention) Type() protoreflect.EnumType {
618
-	return &file_google_protobuf_descriptor_proto_enumTypes[7]
618
+	return &file_google_protobuf_descriptor_proto_enumTypes[8]
619 619
 }
620 620
 
621 621
 func (x FieldOptions_OptionRetention) Number() protoreflect.EnumNumber {
... ...
@@ -694,11 +758,11 @@ func (x FieldOptions_OptionTargetType) String() string {
694 694
 }
695 695
 
696 696
 func (FieldOptions_OptionTargetType) Descriptor() protoreflect.EnumDescriptor {
697
-	return file_google_protobuf_descriptor_proto_enumTypes[8].Descriptor()
697
+	return file_google_protobuf_descriptor_proto_enumTypes[9].Descriptor()
698 698
 }
699 699
 
700 700
 func (FieldOptions_OptionTargetType) Type() protoreflect.EnumType {
701
-	return &file_google_protobuf_descriptor_proto_enumTypes[8]
701
+	return &file_google_protobuf_descriptor_proto_enumTypes[9]
702 702
 }
703 703
 
704 704
 func (x FieldOptions_OptionTargetType) Number() protoreflect.EnumNumber {
... ...
@@ -756,11 +820,11 @@ func (x MethodOptions_IdempotencyLevel) String() string {
756 756
 }
757 757
 
758 758
 func (MethodOptions_IdempotencyLevel) Descriptor() protoreflect.EnumDescriptor {
759
-	return file_google_protobuf_descriptor_proto_enumTypes[9].Descriptor()
759
+	return file_google_protobuf_descriptor_proto_enumTypes[10].Descriptor()
760 760
 }
761 761
 
762 762
 func (MethodOptions_IdempotencyLevel) Type() protoreflect.EnumType {
763
-	return &file_google_protobuf_descriptor_proto_enumTypes[9]
763
+	return &file_google_protobuf_descriptor_proto_enumTypes[10]
764 764
 }
765 765
 
766 766
 func (x MethodOptions_IdempotencyLevel) Number() protoreflect.EnumNumber {
... ...
@@ -818,11 +882,11 @@ func (x FeatureSet_FieldPresence) String() string {
818 818
 }
819 819
 
820 820
 func (FeatureSet_FieldPresence) Descriptor() protoreflect.EnumDescriptor {
821
-	return file_google_protobuf_descriptor_proto_enumTypes[10].Descriptor()
821
+	return file_google_protobuf_descriptor_proto_enumTypes[11].Descriptor()
822 822
 }
823 823
 
824 824
 func (FeatureSet_FieldPresence) Type() protoreflect.EnumType {
825
-	return &file_google_protobuf_descriptor_proto_enumTypes[10]
825
+	return &file_google_protobuf_descriptor_proto_enumTypes[11]
826 826
 }
827 827
 
828 828
 func (x FeatureSet_FieldPresence) Number() protoreflect.EnumNumber {
... ...
@@ -877,11 +941,11 @@ func (x FeatureSet_EnumType) String() string {
877 877
 }
878 878
 
879 879
 func (FeatureSet_EnumType) Descriptor() protoreflect.EnumDescriptor {
880
-	return file_google_protobuf_descriptor_proto_enumTypes[11].Descriptor()
880
+	return file_google_protobuf_descriptor_proto_enumTypes[12].Descriptor()
881 881
 }
882 882
 
883 883
 func (FeatureSet_EnumType) Type() protoreflect.EnumType {
884
-	return &file_google_protobuf_descriptor_proto_enumTypes[11]
884
+	return &file_google_protobuf_descriptor_proto_enumTypes[12]
885 885
 }
886 886
 
887 887
 func (x FeatureSet_EnumType) Number() protoreflect.EnumNumber {
... ...
@@ -936,11 +1000,11 @@ func (x FeatureSet_RepeatedFieldEncoding) String() string {
936 936
 }
937 937
 
938 938
 func (FeatureSet_RepeatedFieldEncoding) Descriptor() protoreflect.EnumDescriptor {
939
-	return file_google_protobuf_descriptor_proto_enumTypes[12].Descriptor()
939
+	return file_google_protobuf_descriptor_proto_enumTypes[13].Descriptor()
940 940
 }
941 941
 
942 942
 func (FeatureSet_RepeatedFieldEncoding) Type() protoreflect.EnumType {
943
-	return &file_google_protobuf_descriptor_proto_enumTypes[12]
943
+	return &file_google_protobuf_descriptor_proto_enumTypes[13]
944 944
 }
945 945
 
946 946
 func (x FeatureSet_RepeatedFieldEncoding) Number() protoreflect.EnumNumber {
... ...
@@ -995,11 +1059,11 @@ func (x FeatureSet_Utf8Validation) String() string {
995 995
 }
996 996
 
997 997
 func (FeatureSet_Utf8Validation) Descriptor() protoreflect.EnumDescriptor {
998
-	return file_google_protobuf_descriptor_proto_enumTypes[13].Descriptor()
998
+	return file_google_protobuf_descriptor_proto_enumTypes[14].Descriptor()
999 999
 }
1000 1000
 
1001 1001
 func (FeatureSet_Utf8Validation) Type() protoreflect.EnumType {
1002
-	return &file_google_protobuf_descriptor_proto_enumTypes[13]
1002
+	return &file_google_protobuf_descriptor_proto_enumTypes[14]
1003 1003
 }
1004 1004
 
1005 1005
 func (x FeatureSet_Utf8Validation) Number() protoreflect.EnumNumber {
... ...
@@ -1054,11 +1118,11 @@ func (x FeatureSet_MessageEncoding) String() string {
1054 1054
 }
1055 1055
 
1056 1056
 func (FeatureSet_MessageEncoding) Descriptor() protoreflect.EnumDescriptor {
1057
-	return file_google_protobuf_descriptor_proto_enumTypes[14].Descriptor()
1057
+	return file_google_protobuf_descriptor_proto_enumTypes[15].Descriptor()
1058 1058
 }
1059 1059
 
1060 1060
 func (FeatureSet_MessageEncoding) Type() protoreflect.EnumType {
1061
-	return &file_google_protobuf_descriptor_proto_enumTypes[14]
1061
+	return &file_google_protobuf_descriptor_proto_enumTypes[15]
1062 1062
 }
1063 1063
 
1064 1064
 func (x FeatureSet_MessageEncoding) Number() protoreflect.EnumNumber {
... ...
@@ -1113,11 +1177,11 @@ func (x FeatureSet_JsonFormat) String() string {
1113 1113
 }
1114 1114
 
1115 1115
 func (FeatureSet_JsonFormat) Descriptor() protoreflect.EnumDescriptor {
1116
-	return file_google_protobuf_descriptor_proto_enumTypes[15].Descriptor()
1116
+	return file_google_protobuf_descriptor_proto_enumTypes[16].Descriptor()
1117 1117
 }
1118 1118
 
1119 1119
 func (FeatureSet_JsonFormat) Type() protoreflect.EnumType {
1120
-	return &file_google_protobuf_descriptor_proto_enumTypes[15]
1120
+	return &file_google_protobuf_descriptor_proto_enumTypes[16]
1121 1121
 }
1122 1122
 
1123 1123
 func (x FeatureSet_JsonFormat) Number() protoreflect.EnumNumber {
... ...
@@ -1172,11 +1236,11 @@ func (x FeatureSet_EnforceNamingStyle) String() string {
1172 1172
 }
1173 1173
 
1174 1174
 func (FeatureSet_EnforceNamingStyle) Descriptor() protoreflect.EnumDescriptor {
1175
-	return file_google_protobuf_descriptor_proto_enumTypes[16].Descriptor()
1175
+	return file_google_protobuf_descriptor_proto_enumTypes[17].Descriptor()
1176 1176
 }
1177 1177
 
1178 1178
 func (FeatureSet_EnforceNamingStyle) Type() protoreflect.EnumType {
1179
-	return &file_google_protobuf_descriptor_proto_enumTypes[16]
1179
+	return &file_google_protobuf_descriptor_proto_enumTypes[17]
1180 1180
 }
1181 1181
 
1182 1182
 func (x FeatureSet_EnforceNamingStyle) Number() protoreflect.EnumNumber {
... ...
@@ -1198,6 +1262,77 @@ func (FeatureSet_EnforceNamingStyle) EnumDescriptor() ([]byte, []int) {
1198 1198
 	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19, 6}
1199 1199
 }
1200 1200
 
1201
+type FeatureSet_VisibilityFeature_DefaultSymbolVisibility int32
1202
+
1203
+const (
1204
+	FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 0
1205
+	// Default pre-EDITION_2024, all UNSET visibility are export.
1206
+	FeatureSet_VisibilityFeature_EXPORT_ALL FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 1
1207
+	// All top-level symbols default to export, nested default to local.
1208
+	FeatureSet_VisibilityFeature_EXPORT_TOP_LEVEL FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 2
1209
+	// All symbols default to local.
1210
+	FeatureSet_VisibilityFeature_LOCAL_ALL FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 3
1211
+	// All symbols local by default. Nested types cannot be exported.
1212
+	// With special case caveat for message { enum {} reserved 1 to max; }
1213
+	// This is the recommended setting for new protos.
1214
+	FeatureSet_VisibilityFeature_STRICT FeatureSet_VisibilityFeature_DefaultSymbolVisibility = 4
1215
+)
1216
+
1217
+// Enum value maps for FeatureSet_VisibilityFeature_DefaultSymbolVisibility.
1218
+var (
1219
+	FeatureSet_VisibilityFeature_DefaultSymbolVisibility_name = map[int32]string{
1220
+		0: "DEFAULT_SYMBOL_VISIBILITY_UNKNOWN",
1221
+		1: "EXPORT_ALL",
1222
+		2: "EXPORT_TOP_LEVEL",
1223
+		3: "LOCAL_ALL",
1224
+		4: "STRICT",
1225
+	}
1226
+	FeatureSet_VisibilityFeature_DefaultSymbolVisibility_value = map[string]int32{
1227
+		"DEFAULT_SYMBOL_VISIBILITY_UNKNOWN": 0,
1228
+		"EXPORT_ALL":                        1,
1229
+		"EXPORT_TOP_LEVEL":                  2,
1230
+		"LOCAL_ALL":                         3,
1231
+		"STRICT":                            4,
1232
+	}
1233
+)
1234
+
1235
+func (x FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Enum() *FeatureSet_VisibilityFeature_DefaultSymbolVisibility {
1236
+	p := new(FeatureSet_VisibilityFeature_DefaultSymbolVisibility)
1237
+	*p = x
1238
+	return p
1239
+}
1240
+
1241
+func (x FeatureSet_VisibilityFeature_DefaultSymbolVisibility) String() string {
1242
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
1243
+}
1244
+
1245
+func (FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Descriptor() protoreflect.EnumDescriptor {
1246
+	return file_google_protobuf_descriptor_proto_enumTypes[18].Descriptor()
1247
+}
1248
+
1249
+func (FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Type() protoreflect.EnumType {
1250
+	return &file_google_protobuf_descriptor_proto_enumTypes[18]
1251
+}
1252
+
1253
+func (x FeatureSet_VisibilityFeature_DefaultSymbolVisibility) Number() protoreflect.EnumNumber {
1254
+	return protoreflect.EnumNumber(x)
1255
+}
1256
+
1257
+// Deprecated: Do not use.
1258
+func (x *FeatureSet_VisibilityFeature_DefaultSymbolVisibility) UnmarshalJSON(b []byte) error {
1259
+	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
1260
+	if err != nil {
1261
+		return err
1262
+	}
1263
+	*x = FeatureSet_VisibilityFeature_DefaultSymbolVisibility(num)
1264
+	return nil
1265
+}
1266
+
1267
+// Deprecated: Use FeatureSet_VisibilityFeature_DefaultSymbolVisibility.Descriptor instead.
1268
+func (FeatureSet_VisibilityFeature_DefaultSymbolVisibility) EnumDescriptor() ([]byte, []int) {
1269
+	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19, 0, 0}
1270
+}
1271
+
1201 1272
 // Represents the identified object's effect on the element in the original
1202 1273
 // .proto file.
1203 1274
 type GeneratedCodeInfo_Annotation_Semantic int32
... ...
@@ -1236,11 +1371,11 @@ func (x GeneratedCodeInfo_Annotation_Semantic) String() string {
1236 1236
 }
1237 1237
 
1238 1238
 func (GeneratedCodeInfo_Annotation_Semantic) Descriptor() protoreflect.EnumDescriptor {
1239
-	return file_google_protobuf_descriptor_proto_enumTypes[17].Descriptor()
1239
+	return file_google_protobuf_descriptor_proto_enumTypes[19].Descriptor()
1240 1240
 }
1241 1241
 
1242 1242
 func (GeneratedCodeInfo_Annotation_Semantic) Type() protoreflect.EnumType {
1243
-	return &file_google_protobuf_descriptor_proto_enumTypes[17]
1243
+	return &file_google_protobuf_descriptor_proto_enumTypes[19]
1244 1244
 }
1245 1245
 
1246 1246
 func (x GeneratedCodeInfo_Annotation_Semantic) Number() protoreflect.EnumNumber {
... ...
@@ -1321,6 +1456,9 @@ type FileDescriptorProto struct {
1321 1321
 	// Indexes of the weak imported files in the dependency list.
1322 1322
 	// For Google-internal migration only. Do not use.
1323 1323
 	WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency,json=weakDependency" json:"weak_dependency,omitempty"`
1324
+	// Names of files imported by this file purely for the purpose of providing
1325
+	// option extensions. These are excluded from the dependency list above.
1326
+	OptionDependency []string `protobuf:"bytes,15,rep,name=option_dependency,json=optionDependency" json:"option_dependency,omitempty"`
1324 1327
 	// All top-level definitions in this file.
1325 1328
 	MessageType []*DescriptorProto        `protobuf:"bytes,4,rep,name=message_type,json=messageType" json:"message_type,omitempty"`
1326 1329
 	EnumType    []*EnumDescriptorProto    `protobuf:"bytes,5,rep,name=enum_type,json=enumType" json:"enum_type,omitempty"`
... ...
@@ -1414,6 +1552,13 @@ func (x *FileDescriptorProto) GetWeakDependency() []int32 {
1414 1414
 	return nil
1415 1415
 }
1416 1416
 
1417
+func (x *FileDescriptorProto) GetOptionDependency() []string {
1418
+	if x != nil {
1419
+		return x.OptionDependency
1420
+	}
1421
+	return nil
1422
+}
1423
+
1417 1424
 func (x *FileDescriptorProto) GetMessageType() []*DescriptorProto {
1418 1425
 	if x != nil {
1419 1426
 		return x.MessageType
... ...
@@ -1484,7 +1629,9 @@ type DescriptorProto struct {
1484 1484
 	ReservedRange  []*DescriptorProto_ReservedRange  `protobuf:"bytes,9,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"`
1485 1485
 	// Reserved field names, which may not be used by fields in the same message.
1486 1486
 	// A given name may only be reserved once.
1487
-	ReservedName  []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"`
1487
+	ReservedName []string `protobuf:"bytes,10,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"`
1488
+	// Support for `export` and `local` keywords on enums.
1489
+	Visibility    *SymbolVisibility `protobuf:"varint,11,opt,name=visibility,enum=google.protobuf.SymbolVisibility" json:"visibility,omitempty"`
1488 1490
 	unknownFields protoimpl.UnknownFields
1489 1491
 	sizeCache     protoimpl.SizeCache
1490 1492
 }
... ...
@@ -1589,6 +1736,13 @@ func (x *DescriptorProto) GetReservedName() []string {
1589 1589
 	return nil
1590 1590
 }
1591 1591
 
1592
+func (x *DescriptorProto) GetVisibility() SymbolVisibility {
1593
+	if x != nil && x.Visibility != nil {
1594
+		return *x.Visibility
1595
+	}
1596
+	return SymbolVisibility_VISIBILITY_UNSET
1597
+}
1598
+
1592 1599
 type ExtensionRangeOptions struct {
1593 1600
 	state protoimpl.MessageState `protogen:"open.v1"`
1594 1601
 	// The parser stores options it doesn't recognize here. See above.
... ...
@@ -1901,7 +2055,9 @@ type EnumDescriptorProto struct {
1901 1901
 	ReservedRange []*EnumDescriptorProto_EnumReservedRange `protobuf:"bytes,4,rep,name=reserved_range,json=reservedRange" json:"reserved_range,omitempty"`
1902 1902
 	// Reserved enum value names, which may not be reused. A given name may only
1903 1903
 	// be reserved once.
1904
-	ReservedName  []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"`
1904
+	ReservedName []string `protobuf:"bytes,5,rep,name=reserved_name,json=reservedName" json:"reserved_name,omitempty"`
1905
+	// Support for `export` and `local` keywords on enums.
1906
+	Visibility    *SymbolVisibility `protobuf:"varint,6,opt,name=visibility,enum=google.protobuf.SymbolVisibility" json:"visibility,omitempty"`
1905 1907
 	unknownFields protoimpl.UnknownFields
1906 1908
 	sizeCache     protoimpl.SizeCache
1907 1909
 }
... ...
@@ -1971,6 +2127,13 @@ func (x *EnumDescriptorProto) GetReservedName() []string {
1971 1971
 	return nil
1972 1972
 }
1973 1973
 
1974
+func (x *EnumDescriptorProto) GetVisibility() SymbolVisibility {
1975
+	if x != nil && x.Visibility != nil {
1976
+		return *x.Visibility
1977
+	}
1978
+	return SymbolVisibility_VISIBILITY_UNSET
1979
+}
1980
+
1974 1981
 // Describes a value within an enum.
1975 1982
 type EnumValueDescriptorProto struct {
1976 1983
 	state         protoimpl.MessageState `protogen:"open.v1"`
... ...
@@ -2710,7 +2873,10 @@ type FieldOptions struct {
2710 2710
 	// for accessors, or it will be completely ignored; in the very least, this
2711 2711
 	// is a formalization for deprecating fields.
2712 2712
 	Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"`
2713
+	// DEPRECATED. DO NOT USE!
2713 2714
 	// For Google-internal migration only. Do not use.
2715
+	//
2716
+	// Deprecated: Marked as deprecated in google/protobuf/descriptor.proto.
2714 2717
 	Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"`
2715 2718
 	// Indicate that the field value should not be printed out when using debug
2716 2719
 	// formats, e.g. when the field contains sensitive credentials.
... ...
@@ -2814,6 +2980,7 @@ func (x *FieldOptions) GetDeprecated() bool {
2814 2814
 	return Default_FieldOptions_Deprecated
2815 2815
 }
2816 2816
 
2817
+// Deprecated: Marked as deprecated in google/protobuf/descriptor.proto.
2817 2818
 func (x *FieldOptions) GetWeak() bool {
2818 2819
 	if x != nil && x.Weak != nil {
2819 2820
 		return *x.Weak
... ...
@@ -3392,17 +3559,18 @@ func (x *UninterpretedOption) GetAggregateValue() string {
3392 3392
 // be designed and implemented to handle this, hopefully before we ever hit a
3393 3393
 // conflict here.
3394 3394
 type FeatureSet struct {
3395
-	state                 protoimpl.MessageState            `protogen:"open.v1"`
3396
-	FieldPresence         *FeatureSet_FieldPresence         `protobuf:"varint,1,opt,name=field_presence,json=fieldPresence,enum=google.protobuf.FeatureSet_FieldPresence" json:"field_presence,omitempty"`
3397
-	EnumType              *FeatureSet_EnumType              `protobuf:"varint,2,opt,name=enum_type,json=enumType,enum=google.protobuf.FeatureSet_EnumType" json:"enum_type,omitempty"`
3398
-	RepeatedFieldEncoding *FeatureSet_RepeatedFieldEncoding `protobuf:"varint,3,opt,name=repeated_field_encoding,json=repeatedFieldEncoding,enum=google.protobuf.FeatureSet_RepeatedFieldEncoding" json:"repeated_field_encoding,omitempty"`
3399
-	Utf8Validation        *FeatureSet_Utf8Validation        `protobuf:"varint,4,opt,name=utf8_validation,json=utf8Validation,enum=google.protobuf.FeatureSet_Utf8Validation" json:"utf8_validation,omitempty"`
3400
-	MessageEncoding       *FeatureSet_MessageEncoding       `protobuf:"varint,5,opt,name=message_encoding,json=messageEncoding,enum=google.protobuf.FeatureSet_MessageEncoding" json:"message_encoding,omitempty"`
3401
-	JsonFormat            *FeatureSet_JsonFormat            `protobuf:"varint,6,opt,name=json_format,json=jsonFormat,enum=google.protobuf.FeatureSet_JsonFormat" json:"json_format,omitempty"`
3402
-	EnforceNamingStyle    *FeatureSet_EnforceNamingStyle    `protobuf:"varint,7,opt,name=enforce_naming_style,json=enforceNamingStyle,enum=google.protobuf.FeatureSet_EnforceNamingStyle" json:"enforce_naming_style,omitempty"`
3403
-	extensionFields       protoimpl.ExtensionFields
3404
-	unknownFields         protoimpl.UnknownFields
3405
-	sizeCache             protoimpl.SizeCache
3395
+	state                   protoimpl.MessageState                                `protogen:"open.v1"`
3396
+	FieldPresence           *FeatureSet_FieldPresence                             `protobuf:"varint,1,opt,name=field_presence,json=fieldPresence,enum=google.protobuf.FeatureSet_FieldPresence" json:"field_presence,omitempty"`
3397
+	EnumType                *FeatureSet_EnumType                                  `protobuf:"varint,2,opt,name=enum_type,json=enumType,enum=google.protobuf.FeatureSet_EnumType" json:"enum_type,omitempty"`
3398
+	RepeatedFieldEncoding   *FeatureSet_RepeatedFieldEncoding                     `protobuf:"varint,3,opt,name=repeated_field_encoding,json=repeatedFieldEncoding,enum=google.protobuf.FeatureSet_RepeatedFieldEncoding" json:"repeated_field_encoding,omitempty"`
3399
+	Utf8Validation          *FeatureSet_Utf8Validation                            `protobuf:"varint,4,opt,name=utf8_validation,json=utf8Validation,enum=google.protobuf.FeatureSet_Utf8Validation" json:"utf8_validation,omitempty"`
3400
+	MessageEncoding         *FeatureSet_MessageEncoding                           `protobuf:"varint,5,opt,name=message_encoding,json=messageEncoding,enum=google.protobuf.FeatureSet_MessageEncoding" json:"message_encoding,omitempty"`
3401
+	JsonFormat              *FeatureSet_JsonFormat                                `protobuf:"varint,6,opt,name=json_format,json=jsonFormat,enum=google.protobuf.FeatureSet_JsonFormat" json:"json_format,omitempty"`
3402
+	EnforceNamingStyle      *FeatureSet_EnforceNamingStyle                        `protobuf:"varint,7,opt,name=enforce_naming_style,json=enforceNamingStyle,enum=google.protobuf.FeatureSet_EnforceNamingStyle" json:"enforce_naming_style,omitempty"`
3403
+	DefaultSymbolVisibility *FeatureSet_VisibilityFeature_DefaultSymbolVisibility `protobuf:"varint,8,opt,name=default_symbol_visibility,json=defaultSymbolVisibility,enum=google.protobuf.FeatureSet_VisibilityFeature_DefaultSymbolVisibility" json:"default_symbol_visibility,omitempty"`
3404
+	extensionFields         protoimpl.ExtensionFields
3405
+	unknownFields           protoimpl.UnknownFields
3406
+	sizeCache               protoimpl.SizeCache
3406 3407
 }
3407 3408
 
3408 3409
 func (x *FeatureSet) Reset() {
... ...
@@ -3484,6 +3652,13 @@ func (x *FeatureSet) GetEnforceNamingStyle() FeatureSet_EnforceNamingStyle {
3484 3484
 	return FeatureSet_ENFORCE_NAMING_STYLE_UNKNOWN
3485 3485
 }
3486 3486
 
3487
+func (x *FeatureSet) GetDefaultSymbolVisibility() FeatureSet_VisibilityFeature_DefaultSymbolVisibility {
3488
+	if x != nil && x.DefaultSymbolVisibility != nil {
3489
+		return *x.DefaultSymbolVisibility
3490
+	}
3491
+	return FeatureSet_VisibilityFeature_DEFAULT_SYMBOL_VISIBILITY_UNKNOWN
3492
+}
3493
+
3487 3494
 // A compiled specification for the defaults of a set of features.  These
3488 3495
 // messages are generated from FeatureSet extensions and can be used to seed
3489 3496
 // feature resolution. The resolution with this object becomes a simple search
... ...
@@ -4144,6 +4319,42 @@ func (x *UninterpretedOption_NamePart) GetIsExtension() bool {
4144 4144
 	return false
4145 4145
 }
4146 4146
 
4147
+type FeatureSet_VisibilityFeature struct {
4148
+	state         protoimpl.MessageState `protogen:"open.v1"`
4149
+	unknownFields protoimpl.UnknownFields
4150
+	sizeCache     protoimpl.SizeCache
4151
+}
4152
+
4153
+func (x *FeatureSet_VisibilityFeature) Reset() {
4154
+	*x = FeatureSet_VisibilityFeature{}
4155
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[30]
4156
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4157
+	ms.StoreMessageInfo(mi)
4158
+}
4159
+
4160
+func (x *FeatureSet_VisibilityFeature) String() string {
4161
+	return protoimpl.X.MessageStringOf(x)
4162
+}
4163
+
4164
+func (*FeatureSet_VisibilityFeature) ProtoMessage() {}
4165
+
4166
+func (x *FeatureSet_VisibilityFeature) ProtoReflect() protoreflect.Message {
4167
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[30]
4168
+	if x != nil {
4169
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4170
+		if ms.LoadMessageInfo() == nil {
4171
+			ms.StoreMessageInfo(mi)
4172
+		}
4173
+		return ms
4174
+	}
4175
+	return mi.MessageOf(x)
4176
+}
4177
+
4178
+// Deprecated: Use FeatureSet_VisibilityFeature.ProtoReflect.Descriptor instead.
4179
+func (*FeatureSet_VisibilityFeature) Descriptor() ([]byte, []int) {
4180
+	return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{19, 0}
4181
+}
4182
+
4147 4183
 // A map from every known edition with a unique set of defaults to its
4148 4184
 // defaults. Not all editions may be contained here.  For a given edition,
4149 4185
 // the defaults at the closest matching edition ordered at or before it should
... ...
@@ -4161,7 +4372,7 @@ type FeatureSetDefaults_FeatureSetEditionDefault struct {
4161 4161
 
4162 4162
 func (x *FeatureSetDefaults_FeatureSetEditionDefault) Reset() {
4163 4163
 	*x = FeatureSetDefaults_FeatureSetEditionDefault{}
4164
-	mi := &file_google_protobuf_descriptor_proto_msgTypes[30]
4164
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[31]
4165 4165
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4166 4166
 	ms.StoreMessageInfo(mi)
4167 4167
 }
... ...
@@ -4173,7 +4384,7 @@ func (x *FeatureSetDefaults_FeatureSetEditionDefault) String() string {
4173 4173
 func (*FeatureSetDefaults_FeatureSetEditionDefault) ProtoMessage() {}
4174 4174
 
4175 4175
 func (x *FeatureSetDefaults_FeatureSetEditionDefault) ProtoReflect() protoreflect.Message {
4176
-	mi := &file_google_protobuf_descriptor_proto_msgTypes[30]
4176
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[31]
4177 4177
 	if x != nil {
4178 4178
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4179 4179
 		if ms.LoadMessageInfo() == nil {
... ...
@@ -4309,7 +4520,7 @@ type SourceCodeInfo_Location struct {
4309 4309
 
4310 4310
 func (x *SourceCodeInfo_Location) Reset() {
4311 4311
 	*x = SourceCodeInfo_Location{}
4312
-	mi := &file_google_protobuf_descriptor_proto_msgTypes[31]
4312
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[32]
4313 4313
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4314 4314
 	ms.StoreMessageInfo(mi)
4315 4315
 }
... ...
@@ -4321,7 +4532,7 @@ func (x *SourceCodeInfo_Location) String() string {
4321 4321
 func (*SourceCodeInfo_Location) ProtoMessage() {}
4322 4322
 
4323 4323
 func (x *SourceCodeInfo_Location) ProtoReflect() protoreflect.Message {
4324
-	mi := &file_google_protobuf_descriptor_proto_msgTypes[31]
4324
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[32]
4325 4325
 	if x != nil {
4326 4326
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4327 4327
 		if ms.LoadMessageInfo() == nil {
... ...
@@ -4393,7 +4604,7 @@ type GeneratedCodeInfo_Annotation struct {
4393 4393
 
4394 4394
 func (x *GeneratedCodeInfo_Annotation) Reset() {
4395 4395
 	*x = GeneratedCodeInfo_Annotation{}
4396
-	mi := &file_google_protobuf_descriptor_proto_msgTypes[32]
4396
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[33]
4397 4397
 	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4398 4398
 	ms.StoreMessageInfo(mi)
4399 4399
 }
... ...
@@ -4405,7 +4616,7 @@ func (x *GeneratedCodeInfo_Annotation) String() string {
4405 4405
 func (*GeneratedCodeInfo_Annotation) ProtoMessage() {}
4406 4406
 
4407 4407
 func (x *GeneratedCodeInfo_Annotation) ProtoReflect() protoreflect.Message {
4408
-	mi := &file_google_protobuf_descriptor_proto_msgTypes[32]
4408
+	mi := &file_google_protobuf_descriptor_proto_msgTypes[33]
4409 4409
 	if x != nil {
4410 4410
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
4411 4411
 		if ms.LoadMessageInfo() == nil {
... ...
@@ -4462,7 +4673,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4462 4462
 	"\n" +
4463 4463
 	" google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"[\n" +
4464 4464
 	"\x11FileDescriptorSet\x128\n" +
4465
-	"\x04file\x18\x01 \x03(\v2$.google.protobuf.FileDescriptorProtoR\x04file*\f\b\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\x98\x05\n" +
4465
+	"\x04file\x18\x01 \x03(\v2$.google.protobuf.FileDescriptorProtoR\x04file*\f\b\x80\xec\xca\xff\x01\x10\x81\xec\xca\xff\x01\"\xc5\x05\n" +
4466 4466
 	"\x13FileDescriptorProto\x12\x12\n" +
4467 4467
 	"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
4468 4468
 	"\apackage\x18\x02 \x01(\tR\apackage\x12\x1e\n" +
... ...
@@ -4471,7 +4682,8 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4471 4471
 	"dependency\x12+\n" +
4472 4472
 	"\x11public_dependency\x18\n" +
4473 4473
 	" \x03(\x05R\x10publicDependency\x12'\n" +
4474
-	"\x0fweak_dependency\x18\v \x03(\x05R\x0eweakDependency\x12C\n" +
4474
+	"\x0fweak_dependency\x18\v \x03(\x05R\x0eweakDependency\x12+\n" +
4475
+	"\x11option_dependency\x18\x0f \x03(\tR\x10optionDependency\x12C\n" +
4475 4476
 	"\fmessage_type\x18\x04 \x03(\v2 .google.protobuf.DescriptorProtoR\vmessageType\x12A\n" +
4476 4477
 	"\tenum_type\x18\x05 \x03(\v2$.google.protobuf.EnumDescriptorProtoR\benumType\x12A\n" +
4477 4478
 	"\aservice\x18\x06 \x03(\v2'.google.protobuf.ServiceDescriptorProtoR\aservice\x12C\n" +
... ...
@@ -4479,7 +4691,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4479 4479
 	"\aoptions\x18\b \x01(\v2\x1c.google.protobuf.FileOptionsR\aoptions\x12I\n" +
4480 4480
 	"\x10source_code_info\x18\t \x01(\v2\x1f.google.protobuf.SourceCodeInfoR\x0esourceCodeInfo\x12\x16\n" +
4481 4481
 	"\x06syntax\x18\f \x01(\tR\x06syntax\x122\n" +
4482
-	"\aedition\x18\x0e \x01(\x0e2\x18.google.protobuf.EditionR\aedition\"\xb9\x06\n" +
4482
+	"\aedition\x18\x0e \x01(\x0e2\x18.google.protobuf.EditionR\aedition\"\xfc\x06\n" +
4483 4483
 	"\x0fDescriptorProto\x12\x12\n" +
4484 4484
 	"\x04name\x18\x01 \x01(\tR\x04name\x12;\n" +
4485 4485
 	"\x05field\x18\x02 \x03(\v2%.google.protobuf.FieldDescriptorProtoR\x05field\x12C\n" +
... ...
@@ -4493,7 +4705,10 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4493 4493
 	"\aoptions\x18\a \x01(\v2\x1f.google.protobuf.MessageOptionsR\aoptions\x12U\n" +
4494 4494
 	"\x0ereserved_range\x18\t \x03(\v2..google.protobuf.DescriptorProto.ReservedRangeR\rreservedRange\x12#\n" +
4495 4495
 	"\rreserved_name\x18\n" +
4496
-	" \x03(\tR\freservedName\x1az\n" +
4496
+	" \x03(\tR\freservedName\x12A\n" +
4497
+	"\n" +
4498
+	"visibility\x18\v \x01(\x0e2!.google.protobuf.SymbolVisibilityR\n" +
4499
+	"visibility\x1az\n" +
4497 4500
 	"\x0eExtensionRange\x12\x14\n" +
4498 4501
 	"\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n" +
4499 4502
 	"\x03end\x18\x02 \x01(\x05R\x03end\x12@\n" +
... ...
@@ -4562,13 +4777,16 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4562 4562
 	"\x0eLABEL_REQUIRED\x10\x02\"c\n" +
4563 4563
 	"\x14OneofDescriptorProto\x12\x12\n" +
4564 4564
 	"\x04name\x18\x01 \x01(\tR\x04name\x127\n" +
4565
-	"\aoptions\x18\x02 \x01(\v2\x1d.google.protobuf.OneofOptionsR\aoptions\"\xe3\x02\n" +
4565
+	"\aoptions\x18\x02 \x01(\v2\x1d.google.protobuf.OneofOptionsR\aoptions\"\xa6\x03\n" +
4566 4566
 	"\x13EnumDescriptorProto\x12\x12\n" +
4567 4567
 	"\x04name\x18\x01 \x01(\tR\x04name\x12?\n" +
4568 4568
 	"\x05value\x18\x02 \x03(\v2).google.protobuf.EnumValueDescriptorProtoR\x05value\x126\n" +
4569 4569
 	"\aoptions\x18\x03 \x01(\v2\x1c.google.protobuf.EnumOptionsR\aoptions\x12]\n" +
4570 4570
 	"\x0ereserved_range\x18\x04 \x03(\v26.google.protobuf.EnumDescriptorProto.EnumReservedRangeR\rreservedRange\x12#\n" +
4571
-	"\rreserved_name\x18\x05 \x03(\tR\freservedName\x1a;\n" +
4571
+	"\rreserved_name\x18\x05 \x03(\tR\freservedName\x12A\n" +
4572
+	"\n" +
4573
+	"visibility\x18\x06 \x01(\x0e2!.google.protobuf.SymbolVisibilityR\n" +
4574
+	"visibility\x1a;\n" +
4572 4575
 	"\x11EnumReservedRange\x12\x14\n" +
4573 4576
 	"\x05start\x18\x01 \x01(\x05R\x05start\x12\x10\n" +
4574 4577
 	"\x03end\x18\x02 \x01(\x05R\x03end\"\x83\x01\n" +
... ...
@@ -4629,7 +4847,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4629 4629
 	"&deprecated_legacy_json_field_conflicts\x18\v \x01(\bB\x02\x18\x01R\"deprecatedLegacyJsonFieldConflicts\x127\n" +
4630 4630
 	"\bfeatures\x18\f \x01(\v2\x1b.google.protobuf.FeatureSetR\bfeatures\x12X\n" +
4631 4631
 	"\x14uninterpreted_option\x18\xe7\a \x03(\v2$.google.protobuf.UninterpretedOptionR\x13uninterpretedOption*\t\b\xe8\a\x10\x80\x80\x80\x80\x02J\x04\b\x04\x10\x05J\x04\b\x05\x10\x06J\x04\b\x06\x10\aJ\x04\b\b\x10\tJ\x04\b\t\x10\n" +
4632
-	"\"\x9d\r\n" +
4632
+	"\"\xa1\r\n" +
4633 4633
 	"\fFieldOptions\x12A\n" +
4634 4634
 	"\x05ctype\x18\x01 \x01(\x0e2#.google.protobuf.FieldOptions.CType:\x06STRINGR\x05ctype\x12\x16\n" +
4635 4635
 	"\x06packed\x18\x02 \x01(\bR\x06packed\x12G\n" +
... ...
@@ -4638,9 +4856,9 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4638 4638
 	"\x0funverified_lazy\x18\x0f \x01(\b:\x05falseR\x0eunverifiedLazy\x12%\n" +
4639 4639
 	"\n" +
4640 4640
 	"deprecated\x18\x03 \x01(\b:\x05falseR\n" +
4641
-	"deprecated\x12\x19\n" +
4641
+	"deprecated\x12\x1d\n" +
4642 4642
 	"\x04weak\x18\n" +
4643
-	" \x01(\b:\x05falseR\x04weak\x12(\n" +
4643
+	" \x01(\b:\x05falseB\x02\x18\x01R\x04weak\x12(\n" +
4644 4644
 	"\fdebug_redact\x18\x10 \x01(\b:\x05falseR\vdebugRedact\x12K\n" +
4645 4645
 	"\tretention\x18\x11 \x01(\x0e2-.google.protobuf.FieldOptions.OptionRetentionR\tretention\x12H\n" +
4646 4646
 	"\atargets\x18\x13 \x03(\x0e2..google.protobuf.FieldOptions.OptionTargetTypeR\atargets\x12W\n" +
... ...
@@ -4728,7 +4946,7 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4728 4728
 	"\x0faggregate_value\x18\b \x01(\tR\x0eaggregateValue\x1aJ\n" +
4729 4729
 	"\bNamePart\x12\x1b\n" +
4730 4730
 	"\tname_part\x18\x01 \x02(\tR\bnamePart\x12!\n" +
4731
-	"\fis_extension\x18\x02 \x02(\bR\visExtension\"\xae\f\n" +
4731
+	"\fis_extension\x18\x02 \x02(\bR\visExtension\"\x8e\x0f\n" +
4732 4732
 	"\n" +
4733 4733
 	"FeatureSet\x12\x91\x01\n" +
4734 4734
 	"\x0efield_presence\x18\x01 \x01(\x0e2).google.protobuf.FeatureSet.FieldPresenceB?\x88\x01\x01\x98\x01\x04\x98\x01\x01\xa2\x01\r\x12\bEXPLICIT\x18\x84\a\xa2\x01\r\x12\bIMPLICIT\x18\xe7\a\xa2\x01\r\x12\bEXPLICIT\x18\xe8\a\xb2\x01\x03\b\xe8\aR\rfieldPresence\x12l\n" +
... ...
@@ -4739,7 +4957,18 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4739 4739
 	"\vjson_format\x18\x06 \x01(\x0e2&.google.protobuf.FeatureSet.JsonFormatB9\x88\x01\x01\x98\x01\x03\x98\x01\x06\x98\x01\x01\xa2\x01\x17\x12\x12LEGACY_BEST_EFFORT\x18\x84\a\xa2\x01\n" +
4740 4740
 	"\x12\x05ALLOW\x18\xe7\a\xb2\x01\x03\b\xe8\aR\n" +
4741 4741
 	"jsonFormat\x12\xab\x01\n" +
4742
-	"\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBI\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\"\\\n" +
4742
+	"\x14enforce_naming_style\x18\a \x01(\x0e2..google.protobuf.FeatureSet.EnforceNamingStyleBI\x88\x01\x02\x98\x01\x01\x98\x01\x02\x98\x01\x03\x98\x01\x04\x98\x01\x05\x98\x01\x06\x98\x01\a\x98\x01\b\x98\x01\t\xa2\x01\x11\x12\fSTYLE_LEGACY\x18\x84\a\xa2\x01\x0e\x12\tSTYLE2024\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x12enforceNamingStyle\x12\xb9\x01\n" +
4743
+	"\x19default_symbol_visibility\x18\b \x01(\x0e2E.google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibilityB6\x88\x01\x02\x98\x01\x01\xa2\x01\x0f\x12\n" +
4744
+	"EXPORT_ALL\x18\x84\a\xa2\x01\x15\x12\x10EXPORT_TOP_LEVEL\x18\xe9\a\xb2\x01\x03\b\xe9\aR\x17defaultSymbolVisibility\x1a\xa1\x01\n" +
4745
+	"\x11VisibilityFeature\"\x81\x01\n" +
4746
+	"\x17DefaultSymbolVisibility\x12%\n" +
4747
+	"!DEFAULT_SYMBOL_VISIBILITY_UNKNOWN\x10\x00\x12\x0e\n" +
4748
+	"\n" +
4749
+	"EXPORT_ALL\x10\x01\x12\x14\n" +
4750
+	"\x10EXPORT_TOP_LEVEL\x10\x02\x12\r\n" +
4751
+	"\tLOCAL_ALL\x10\x03\x12\n" +
4752
+	"\n" +
4753
+	"\x06STRICT\x10\x04J\b\b\x01\x10\x80\x80\x80\x80\x02\"\\\n" +
4743 4754
 	"\rFieldPresence\x12\x1a\n" +
4744 4755
 	"\x16FIELD_PRESENCE_UNKNOWN\x10\x00\x12\f\n" +
4745 4756
 	"\bEXPLICIT\x10\x01\x12\f\n" +
... ...
@@ -4817,7 +5046,11 @@ const file_google_protobuf_descriptor_proto_rawDesc = "" +
4817 4817
 	"\x17EDITION_99997_TEST_ONLY\x10\x9d\x8d\x06\x12\x1d\n" +
4818 4818
 	"\x17EDITION_99998_TEST_ONLY\x10\x9e\x8d\x06\x12\x1d\n" +
4819 4819
 	"\x17EDITION_99999_TEST_ONLY\x10\x9f\x8d\x06\x12\x13\n" +
4820
-	"\vEDITION_MAX\x10\xff\xff\xff\xff\aB~\n" +
4820
+	"\vEDITION_MAX\x10\xff\xff\xff\xff\a*U\n" +
4821
+	"\x10SymbolVisibility\x12\x14\n" +
4822
+	"\x10VISIBILITY_UNSET\x10\x00\x12\x14\n" +
4823
+	"\x10VISIBILITY_LOCAL\x10\x01\x12\x15\n" +
4824
+	"\x11VISIBILITY_EXPORT\x10\x02B~\n" +
4821 4825
 	"\x13com.google.protobufB\x10DescriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection"
4822 4826
 
4823 4827
 var (
... ...
@@ -4832,145 +5065,151 @@ func file_google_protobuf_descriptor_proto_rawDescGZIP() []byte {
4832 4832
 	return file_google_protobuf_descriptor_proto_rawDescData
4833 4833
 }
4834 4834
 
4835
-var file_google_protobuf_descriptor_proto_enumTypes = make([]protoimpl.EnumInfo, 18)
4836
-var file_google_protobuf_descriptor_proto_msgTypes = make([]protoimpl.MessageInfo, 33)
4835
+var file_google_protobuf_descriptor_proto_enumTypes = make([]protoimpl.EnumInfo, 20)
4836
+var file_google_protobuf_descriptor_proto_msgTypes = make([]protoimpl.MessageInfo, 34)
4837 4837
 var file_google_protobuf_descriptor_proto_goTypes = []any{
4838
-	(Edition)(0), // 0: google.protobuf.Edition
4839
-	(ExtensionRangeOptions_VerificationState)(0),        // 1: google.protobuf.ExtensionRangeOptions.VerificationState
4840
-	(FieldDescriptorProto_Type)(0),                      // 2: google.protobuf.FieldDescriptorProto.Type
4841
-	(FieldDescriptorProto_Label)(0),                     // 3: google.protobuf.FieldDescriptorProto.Label
4842
-	(FileOptions_OptimizeMode)(0),                       // 4: google.protobuf.FileOptions.OptimizeMode
4843
-	(FieldOptions_CType)(0),                             // 5: google.protobuf.FieldOptions.CType
4844
-	(FieldOptions_JSType)(0),                            // 6: google.protobuf.FieldOptions.JSType
4845
-	(FieldOptions_OptionRetention)(0),                   // 7: google.protobuf.FieldOptions.OptionRetention
4846
-	(FieldOptions_OptionTargetType)(0),                  // 8: google.protobuf.FieldOptions.OptionTargetType
4847
-	(MethodOptions_IdempotencyLevel)(0),                 // 9: google.protobuf.MethodOptions.IdempotencyLevel
4848
-	(FeatureSet_FieldPresence)(0),                       // 10: google.protobuf.FeatureSet.FieldPresence
4849
-	(FeatureSet_EnumType)(0),                            // 11: google.protobuf.FeatureSet.EnumType
4850
-	(FeatureSet_RepeatedFieldEncoding)(0),               // 12: google.protobuf.FeatureSet.RepeatedFieldEncoding
4851
-	(FeatureSet_Utf8Validation)(0),                      // 13: google.protobuf.FeatureSet.Utf8Validation
4852
-	(FeatureSet_MessageEncoding)(0),                     // 14: google.protobuf.FeatureSet.MessageEncoding
4853
-	(FeatureSet_JsonFormat)(0),                          // 15: google.protobuf.FeatureSet.JsonFormat
4854
-	(FeatureSet_EnforceNamingStyle)(0),                  // 16: google.protobuf.FeatureSet.EnforceNamingStyle
4855
-	(GeneratedCodeInfo_Annotation_Semantic)(0),          // 17: google.protobuf.GeneratedCodeInfo.Annotation.Semantic
4856
-	(*FileDescriptorSet)(nil),                           // 18: google.protobuf.FileDescriptorSet
4857
-	(*FileDescriptorProto)(nil),                         // 19: google.protobuf.FileDescriptorProto
4858
-	(*DescriptorProto)(nil),                             // 20: google.protobuf.DescriptorProto
4859
-	(*ExtensionRangeOptions)(nil),                       // 21: google.protobuf.ExtensionRangeOptions
4860
-	(*FieldDescriptorProto)(nil),                        // 22: google.protobuf.FieldDescriptorProto
4861
-	(*OneofDescriptorProto)(nil),                        // 23: google.protobuf.OneofDescriptorProto
4862
-	(*EnumDescriptorProto)(nil),                         // 24: google.protobuf.EnumDescriptorProto
4863
-	(*EnumValueDescriptorProto)(nil),                    // 25: google.protobuf.EnumValueDescriptorProto
4864
-	(*ServiceDescriptorProto)(nil),                      // 26: google.protobuf.ServiceDescriptorProto
4865
-	(*MethodDescriptorProto)(nil),                       // 27: google.protobuf.MethodDescriptorProto
4866
-	(*FileOptions)(nil),                                 // 28: google.protobuf.FileOptions
4867
-	(*MessageOptions)(nil),                              // 29: google.protobuf.MessageOptions
4868
-	(*FieldOptions)(nil),                                // 30: google.protobuf.FieldOptions
4869
-	(*OneofOptions)(nil),                                // 31: google.protobuf.OneofOptions
4870
-	(*EnumOptions)(nil),                                 // 32: google.protobuf.EnumOptions
4871
-	(*EnumValueOptions)(nil),                            // 33: google.protobuf.EnumValueOptions
4872
-	(*ServiceOptions)(nil),                              // 34: google.protobuf.ServiceOptions
4873
-	(*MethodOptions)(nil),                               // 35: google.protobuf.MethodOptions
4874
-	(*UninterpretedOption)(nil),                         // 36: google.protobuf.UninterpretedOption
4875
-	(*FeatureSet)(nil),                                  // 37: google.protobuf.FeatureSet
4876
-	(*FeatureSetDefaults)(nil),                          // 38: google.protobuf.FeatureSetDefaults
4877
-	(*SourceCodeInfo)(nil),                              // 39: google.protobuf.SourceCodeInfo
4878
-	(*GeneratedCodeInfo)(nil),                           // 40: google.protobuf.GeneratedCodeInfo
4879
-	(*DescriptorProto_ExtensionRange)(nil),              // 41: google.protobuf.DescriptorProto.ExtensionRange
4880
-	(*DescriptorProto_ReservedRange)(nil),               // 42: google.protobuf.DescriptorProto.ReservedRange
4881
-	(*ExtensionRangeOptions_Declaration)(nil),           // 43: google.protobuf.ExtensionRangeOptions.Declaration
4882
-	(*EnumDescriptorProto_EnumReservedRange)(nil),       // 44: google.protobuf.EnumDescriptorProto.EnumReservedRange
4883
-	(*FieldOptions_EditionDefault)(nil),                 // 45: google.protobuf.FieldOptions.EditionDefault
4884
-	(*FieldOptions_FeatureSupport)(nil),                 // 46: google.protobuf.FieldOptions.FeatureSupport
4885
-	(*UninterpretedOption_NamePart)(nil),                // 47: google.protobuf.UninterpretedOption.NamePart
4886
-	(*FeatureSetDefaults_FeatureSetEditionDefault)(nil), // 48: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault
4887
-	(*SourceCodeInfo_Location)(nil),                     // 49: google.protobuf.SourceCodeInfo.Location
4888
-	(*GeneratedCodeInfo_Annotation)(nil),                // 50: google.protobuf.GeneratedCodeInfo.Annotation
4838
+	(Edition)(0),          // 0: google.protobuf.Edition
4839
+	(SymbolVisibility)(0), // 1: google.protobuf.SymbolVisibility
4840
+	(ExtensionRangeOptions_VerificationState)(0),              // 2: google.protobuf.ExtensionRangeOptions.VerificationState
4841
+	(FieldDescriptorProto_Type)(0),                            // 3: google.protobuf.FieldDescriptorProto.Type
4842
+	(FieldDescriptorProto_Label)(0),                           // 4: google.protobuf.FieldDescriptorProto.Label
4843
+	(FileOptions_OptimizeMode)(0),                             // 5: google.protobuf.FileOptions.OptimizeMode
4844
+	(FieldOptions_CType)(0),                                   // 6: google.protobuf.FieldOptions.CType
4845
+	(FieldOptions_JSType)(0),                                  // 7: google.protobuf.FieldOptions.JSType
4846
+	(FieldOptions_OptionRetention)(0),                         // 8: google.protobuf.FieldOptions.OptionRetention
4847
+	(FieldOptions_OptionTargetType)(0),                        // 9: google.protobuf.FieldOptions.OptionTargetType
4848
+	(MethodOptions_IdempotencyLevel)(0),                       // 10: google.protobuf.MethodOptions.IdempotencyLevel
4849
+	(FeatureSet_FieldPresence)(0),                             // 11: google.protobuf.FeatureSet.FieldPresence
4850
+	(FeatureSet_EnumType)(0),                                  // 12: google.protobuf.FeatureSet.EnumType
4851
+	(FeatureSet_RepeatedFieldEncoding)(0),                     // 13: google.protobuf.FeatureSet.RepeatedFieldEncoding
4852
+	(FeatureSet_Utf8Validation)(0),                            // 14: google.protobuf.FeatureSet.Utf8Validation
4853
+	(FeatureSet_MessageEncoding)(0),                           // 15: google.protobuf.FeatureSet.MessageEncoding
4854
+	(FeatureSet_JsonFormat)(0),                                // 16: google.protobuf.FeatureSet.JsonFormat
4855
+	(FeatureSet_EnforceNamingStyle)(0),                        // 17: google.protobuf.FeatureSet.EnforceNamingStyle
4856
+	(FeatureSet_VisibilityFeature_DefaultSymbolVisibility)(0), // 18: google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility
4857
+	(GeneratedCodeInfo_Annotation_Semantic)(0),                // 19: google.protobuf.GeneratedCodeInfo.Annotation.Semantic
4858
+	(*FileDescriptorSet)(nil),                                 // 20: google.protobuf.FileDescriptorSet
4859
+	(*FileDescriptorProto)(nil),                               // 21: google.protobuf.FileDescriptorProto
4860
+	(*DescriptorProto)(nil),                                   // 22: google.protobuf.DescriptorProto
4861
+	(*ExtensionRangeOptions)(nil),                             // 23: google.protobuf.ExtensionRangeOptions
4862
+	(*FieldDescriptorProto)(nil),                              // 24: google.protobuf.FieldDescriptorProto
4863
+	(*OneofDescriptorProto)(nil),                              // 25: google.protobuf.OneofDescriptorProto
4864
+	(*EnumDescriptorProto)(nil),                               // 26: google.protobuf.EnumDescriptorProto
4865
+	(*EnumValueDescriptorProto)(nil),                          // 27: google.protobuf.EnumValueDescriptorProto
4866
+	(*ServiceDescriptorProto)(nil),                            // 28: google.protobuf.ServiceDescriptorProto
4867
+	(*MethodDescriptorProto)(nil),                             // 29: google.protobuf.MethodDescriptorProto
4868
+	(*FileOptions)(nil),                                       // 30: google.protobuf.FileOptions
4869
+	(*MessageOptions)(nil),                                    // 31: google.protobuf.MessageOptions
4870
+	(*FieldOptions)(nil),                                      // 32: google.protobuf.FieldOptions
4871
+	(*OneofOptions)(nil),                                      // 33: google.protobuf.OneofOptions
4872
+	(*EnumOptions)(nil),                                       // 34: google.protobuf.EnumOptions
4873
+	(*EnumValueOptions)(nil),                                  // 35: google.protobuf.EnumValueOptions
4874
+	(*ServiceOptions)(nil),                                    // 36: google.protobuf.ServiceOptions
4875
+	(*MethodOptions)(nil),                                     // 37: google.protobuf.MethodOptions
4876
+	(*UninterpretedOption)(nil),                               // 38: google.protobuf.UninterpretedOption
4877
+	(*FeatureSet)(nil),                                        // 39: google.protobuf.FeatureSet
4878
+	(*FeatureSetDefaults)(nil),                                // 40: google.protobuf.FeatureSetDefaults
4879
+	(*SourceCodeInfo)(nil),                                    // 41: google.protobuf.SourceCodeInfo
4880
+	(*GeneratedCodeInfo)(nil),                                 // 42: google.protobuf.GeneratedCodeInfo
4881
+	(*DescriptorProto_ExtensionRange)(nil),                    // 43: google.protobuf.DescriptorProto.ExtensionRange
4882
+	(*DescriptorProto_ReservedRange)(nil),                     // 44: google.protobuf.DescriptorProto.ReservedRange
4883
+	(*ExtensionRangeOptions_Declaration)(nil),                 // 45: google.protobuf.ExtensionRangeOptions.Declaration
4884
+	(*EnumDescriptorProto_EnumReservedRange)(nil),             // 46: google.protobuf.EnumDescriptorProto.EnumReservedRange
4885
+	(*FieldOptions_EditionDefault)(nil),                       // 47: google.protobuf.FieldOptions.EditionDefault
4886
+	(*FieldOptions_FeatureSupport)(nil),                       // 48: google.protobuf.FieldOptions.FeatureSupport
4887
+	(*UninterpretedOption_NamePart)(nil),                      // 49: google.protobuf.UninterpretedOption.NamePart
4888
+	(*FeatureSet_VisibilityFeature)(nil),                      // 50: google.protobuf.FeatureSet.VisibilityFeature
4889
+	(*FeatureSetDefaults_FeatureSetEditionDefault)(nil),       // 51: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault
4890
+	(*SourceCodeInfo_Location)(nil),                           // 52: google.protobuf.SourceCodeInfo.Location
4891
+	(*GeneratedCodeInfo_Annotation)(nil),                      // 53: google.protobuf.GeneratedCodeInfo.Annotation
4889 4892
 }
4890 4893
 var file_google_protobuf_descriptor_proto_depIdxs = []int32{
4891
-	19, // 0: google.protobuf.FileDescriptorSet.file:type_name -> google.protobuf.FileDescriptorProto
4892
-	20, // 1: google.protobuf.FileDescriptorProto.message_type:type_name -> google.protobuf.DescriptorProto
4893
-	24, // 2: google.protobuf.FileDescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto
4894
-	26, // 3: google.protobuf.FileDescriptorProto.service:type_name -> google.protobuf.ServiceDescriptorProto
4895
-	22, // 4: google.protobuf.FileDescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto
4896
-	28, // 5: google.protobuf.FileDescriptorProto.options:type_name -> google.protobuf.FileOptions
4897
-	39, // 6: google.protobuf.FileDescriptorProto.source_code_info:type_name -> google.protobuf.SourceCodeInfo
4894
+	21, // 0: google.protobuf.FileDescriptorSet.file:type_name -> google.protobuf.FileDescriptorProto
4895
+	22, // 1: google.protobuf.FileDescriptorProto.message_type:type_name -> google.protobuf.DescriptorProto
4896
+	26, // 2: google.protobuf.FileDescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto
4897
+	28, // 3: google.protobuf.FileDescriptorProto.service:type_name -> google.protobuf.ServiceDescriptorProto
4898
+	24, // 4: google.protobuf.FileDescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto
4899
+	30, // 5: google.protobuf.FileDescriptorProto.options:type_name -> google.protobuf.FileOptions
4900
+	41, // 6: google.protobuf.FileDescriptorProto.source_code_info:type_name -> google.protobuf.SourceCodeInfo
4898 4901
 	0,  // 7: google.protobuf.FileDescriptorProto.edition:type_name -> google.protobuf.Edition
4899
-	22, // 8: google.protobuf.DescriptorProto.field:type_name -> google.protobuf.FieldDescriptorProto
4900
-	22, // 9: google.protobuf.DescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto
4901
-	20, // 10: google.protobuf.DescriptorProto.nested_type:type_name -> google.protobuf.DescriptorProto
4902
-	24, // 11: google.protobuf.DescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto
4903
-	41, // 12: google.protobuf.DescriptorProto.extension_range:type_name -> google.protobuf.DescriptorProto.ExtensionRange
4904
-	23, // 13: google.protobuf.DescriptorProto.oneof_decl:type_name -> google.protobuf.OneofDescriptorProto
4905
-	29, // 14: google.protobuf.DescriptorProto.options:type_name -> google.protobuf.MessageOptions
4906
-	42, // 15: google.protobuf.DescriptorProto.reserved_range:type_name -> google.protobuf.DescriptorProto.ReservedRange
4907
-	36, // 16: google.protobuf.ExtensionRangeOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4908
-	43, // 17: google.protobuf.ExtensionRangeOptions.declaration:type_name -> google.protobuf.ExtensionRangeOptions.Declaration
4909
-	37, // 18: google.protobuf.ExtensionRangeOptions.features:type_name -> google.protobuf.FeatureSet
4910
-	1,  // 19: google.protobuf.ExtensionRangeOptions.verification:type_name -> google.protobuf.ExtensionRangeOptions.VerificationState
4911
-	3,  // 20: google.protobuf.FieldDescriptorProto.label:type_name -> google.protobuf.FieldDescriptorProto.Label
4912
-	2,  // 21: google.protobuf.FieldDescriptorProto.type:type_name -> google.protobuf.FieldDescriptorProto.Type
4913
-	30, // 22: google.protobuf.FieldDescriptorProto.options:type_name -> google.protobuf.FieldOptions
4914
-	31, // 23: google.protobuf.OneofDescriptorProto.options:type_name -> google.protobuf.OneofOptions
4915
-	25, // 24: google.protobuf.EnumDescriptorProto.value:type_name -> google.protobuf.EnumValueDescriptorProto
4916
-	32, // 25: google.protobuf.EnumDescriptorProto.options:type_name -> google.protobuf.EnumOptions
4917
-	44, // 26: google.protobuf.EnumDescriptorProto.reserved_range:type_name -> google.protobuf.EnumDescriptorProto.EnumReservedRange
4918
-	33, // 27: google.protobuf.EnumValueDescriptorProto.options:type_name -> google.protobuf.EnumValueOptions
4919
-	27, // 28: google.protobuf.ServiceDescriptorProto.method:type_name -> google.protobuf.MethodDescriptorProto
4920
-	34, // 29: google.protobuf.ServiceDescriptorProto.options:type_name -> google.protobuf.ServiceOptions
4921
-	35, // 30: google.protobuf.MethodDescriptorProto.options:type_name -> google.protobuf.MethodOptions
4922
-	4,  // 31: google.protobuf.FileOptions.optimize_for:type_name -> google.protobuf.FileOptions.OptimizeMode
4923
-	37, // 32: google.protobuf.FileOptions.features:type_name -> google.protobuf.FeatureSet
4924
-	36, // 33: google.protobuf.FileOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4925
-	37, // 34: google.protobuf.MessageOptions.features:type_name -> google.protobuf.FeatureSet
4926
-	36, // 35: google.protobuf.MessageOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4927
-	5,  // 36: google.protobuf.FieldOptions.ctype:type_name -> google.protobuf.FieldOptions.CType
4928
-	6,  // 37: google.protobuf.FieldOptions.jstype:type_name -> google.protobuf.FieldOptions.JSType
4929
-	7,  // 38: google.protobuf.FieldOptions.retention:type_name -> google.protobuf.FieldOptions.OptionRetention
4930
-	8,  // 39: google.protobuf.FieldOptions.targets:type_name -> google.protobuf.FieldOptions.OptionTargetType
4931
-	45, // 40: google.protobuf.FieldOptions.edition_defaults:type_name -> google.protobuf.FieldOptions.EditionDefault
4932
-	37, // 41: google.protobuf.FieldOptions.features:type_name -> google.protobuf.FeatureSet
4933
-	46, // 42: google.protobuf.FieldOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport
4934
-	36, // 43: google.protobuf.FieldOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4935
-	37, // 44: google.protobuf.OneofOptions.features:type_name -> google.protobuf.FeatureSet
4936
-	36, // 45: google.protobuf.OneofOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4937
-	37, // 46: google.protobuf.EnumOptions.features:type_name -> google.protobuf.FeatureSet
4938
-	36, // 47: google.protobuf.EnumOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4939
-	37, // 48: google.protobuf.EnumValueOptions.features:type_name -> google.protobuf.FeatureSet
4940
-	46, // 49: google.protobuf.EnumValueOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport
4941
-	36, // 50: google.protobuf.EnumValueOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4942
-	37, // 51: google.protobuf.ServiceOptions.features:type_name -> google.protobuf.FeatureSet
4943
-	36, // 52: google.protobuf.ServiceOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4944
-	9,  // 53: google.protobuf.MethodOptions.idempotency_level:type_name -> google.protobuf.MethodOptions.IdempotencyLevel
4945
-	37, // 54: google.protobuf.MethodOptions.features:type_name -> google.protobuf.FeatureSet
4946
-	36, // 55: google.protobuf.MethodOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4947
-	47, // 56: google.protobuf.UninterpretedOption.name:type_name -> google.protobuf.UninterpretedOption.NamePart
4948
-	10, // 57: google.protobuf.FeatureSet.field_presence:type_name -> google.protobuf.FeatureSet.FieldPresence
4949
-	11, // 58: google.protobuf.FeatureSet.enum_type:type_name -> google.protobuf.FeatureSet.EnumType
4950
-	12, // 59: google.protobuf.FeatureSet.repeated_field_encoding:type_name -> google.protobuf.FeatureSet.RepeatedFieldEncoding
4951
-	13, // 60: google.protobuf.FeatureSet.utf8_validation:type_name -> google.protobuf.FeatureSet.Utf8Validation
4952
-	14, // 61: google.protobuf.FeatureSet.message_encoding:type_name -> google.protobuf.FeatureSet.MessageEncoding
4953
-	15, // 62: google.protobuf.FeatureSet.json_format:type_name -> google.protobuf.FeatureSet.JsonFormat
4954
-	16, // 63: google.protobuf.FeatureSet.enforce_naming_style:type_name -> google.protobuf.FeatureSet.EnforceNamingStyle
4955
-	48, // 64: google.protobuf.FeatureSetDefaults.defaults:type_name -> google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault
4956
-	0,  // 65: google.protobuf.FeatureSetDefaults.minimum_edition:type_name -> google.protobuf.Edition
4957
-	0,  // 66: google.protobuf.FeatureSetDefaults.maximum_edition:type_name -> google.protobuf.Edition
4958
-	49, // 67: google.protobuf.SourceCodeInfo.location:type_name -> google.protobuf.SourceCodeInfo.Location
4959
-	50, // 68: google.protobuf.GeneratedCodeInfo.annotation:type_name -> google.protobuf.GeneratedCodeInfo.Annotation
4960
-	21, // 69: google.protobuf.DescriptorProto.ExtensionRange.options:type_name -> google.protobuf.ExtensionRangeOptions
4961
-	0,  // 70: google.protobuf.FieldOptions.EditionDefault.edition:type_name -> google.protobuf.Edition
4962
-	0,  // 71: google.protobuf.FieldOptions.FeatureSupport.edition_introduced:type_name -> google.protobuf.Edition
4963
-	0,  // 72: google.protobuf.FieldOptions.FeatureSupport.edition_deprecated:type_name -> google.protobuf.Edition
4964
-	0,  // 73: google.protobuf.FieldOptions.FeatureSupport.edition_removed:type_name -> google.protobuf.Edition
4965
-	0,  // 74: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition:type_name -> google.protobuf.Edition
4966
-	37, // 75: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features:type_name -> google.protobuf.FeatureSet
4967
-	37, // 76: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features:type_name -> google.protobuf.FeatureSet
4968
-	17, // 77: google.protobuf.GeneratedCodeInfo.Annotation.semantic:type_name -> google.protobuf.GeneratedCodeInfo.Annotation.Semantic
4969
-	78, // [78:78] is the sub-list for method output_type
4970
-	78, // [78:78] is the sub-list for method input_type
4971
-	78, // [78:78] is the sub-list for extension type_name
4972
-	78, // [78:78] is the sub-list for extension extendee
4973
-	0,  // [0:78] is the sub-list for field type_name
4902
+	24, // 8: google.protobuf.DescriptorProto.field:type_name -> google.protobuf.FieldDescriptorProto
4903
+	24, // 9: google.protobuf.DescriptorProto.extension:type_name -> google.protobuf.FieldDescriptorProto
4904
+	22, // 10: google.protobuf.DescriptorProto.nested_type:type_name -> google.protobuf.DescriptorProto
4905
+	26, // 11: google.protobuf.DescriptorProto.enum_type:type_name -> google.protobuf.EnumDescriptorProto
4906
+	43, // 12: google.protobuf.DescriptorProto.extension_range:type_name -> google.protobuf.DescriptorProto.ExtensionRange
4907
+	25, // 13: google.protobuf.DescriptorProto.oneof_decl:type_name -> google.protobuf.OneofDescriptorProto
4908
+	31, // 14: google.protobuf.DescriptorProto.options:type_name -> google.protobuf.MessageOptions
4909
+	44, // 15: google.protobuf.DescriptorProto.reserved_range:type_name -> google.protobuf.DescriptorProto.ReservedRange
4910
+	1,  // 16: google.protobuf.DescriptorProto.visibility:type_name -> google.protobuf.SymbolVisibility
4911
+	38, // 17: google.protobuf.ExtensionRangeOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4912
+	45, // 18: google.protobuf.ExtensionRangeOptions.declaration:type_name -> google.protobuf.ExtensionRangeOptions.Declaration
4913
+	39, // 19: google.protobuf.ExtensionRangeOptions.features:type_name -> google.protobuf.FeatureSet
4914
+	2,  // 20: google.protobuf.ExtensionRangeOptions.verification:type_name -> google.protobuf.ExtensionRangeOptions.VerificationState
4915
+	4,  // 21: google.protobuf.FieldDescriptorProto.label:type_name -> google.protobuf.FieldDescriptorProto.Label
4916
+	3,  // 22: google.protobuf.FieldDescriptorProto.type:type_name -> google.protobuf.FieldDescriptorProto.Type
4917
+	32, // 23: google.protobuf.FieldDescriptorProto.options:type_name -> google.protobuf.FieldOptions
4918
+	33, // 24: google.protobuf.OneofDescriptorProto.options:type_name -> google.protobuf.OneofOptions
4919
+	27, // 25: google.protobuf.EnumDescriptorProto.value:type_name -> google.protobuf.EnumValueDescriptorProto
4920
+	34, // 26: google.protobuf.EnumDescriptorProto.options:type_name -> google.protobuf.EnumOptions
4921
+	46, // 27: google.protobuf.EnumDescriptorProto.reserved_range:type_name -> google.protobuf.EnumDescriptorProto.EnumReservedRange
4922
+	1,  // 28: google.protobuf.EnumDescriptorProto.visibility:type_name -> google.protobuf.SymbolVisibility
4923
+	35, // 29: google.protobuf.EnumValueDescriptorProto.options:type_name -> google.protobuf.EnumValueOptions
4924
+	29, // 30: google.protobuf.ServiceDescriptorProto.method:type_name -> google.protobuf.MethodDescriptorProto
4925
+	36, // 31: google.protobuf.ServiceDescriptorProto.options:type_name -> google.protobuf.ServiceOptions
4926
+	37, // 32: google.protobuf.MethodDescriptorProto.options:type_name -> google.protobuf.MethodOptions
4927
+	5,  // 33: google.protobuf.FileOptions.optimize_for:type_name -> google.protobuf.FileOptions.OptimizeMode
4928
+	39, // 34: google.protobuf.FileOptions.features:type_name -> google.protobuf.FeatureSet
4929
+	38, // 35: google.protobuf.FileOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4930
+	39, // 36: google.protobuf.MessageOptions.features:type_name -> google.protobuf.FeatureSet
4931
+	38, // 37: google.protobuf.MessageOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4932
+	6,  // 38: google.protobuf.FieldOptions.ctype:type_name -> google.protobuf.FieldOptions.CType
4933
+	7,  // 39: google.protobuf.FieldOptions.jstype:type_name -> google.protobuf.FieldOptions.JSType
4934
+	8,  // 40: google.protobuf.FieldOptions.retention:type_name -> google.protobuf.FieldOptions.OptionRetention
4935
+	9,  // 41: google.protobuf.FieldOptions.targets:type_name -> google.protobuf.FieldOptions.OptionTargetType
4936
+	47, // 42: google.protobuf.FieldOptions.edition_defaults:type_name -> google.protobuf.FieldOptions.EditionDefault
4937
+	39, // 43: google.protobuf.FieldOptions.features:type_name -> google.protobuf.FeatureSet
4938
+	48, // 44: google.protobuf.FieldOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport
4939
+	38, // 45: google.protobuf.FieldOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4940
+	39, // 46: google.protobuf.OneofOptions.features:type_name -> google.protobuf.FeatureSet
4941
+	38, // 47: google.protobuf.OneofOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4942
+	39, // 48: google.protobuf.EnumOptions.features:type_name -> google.protobuf.FeatureSet
4943
+	38, // 49: google.protobuf.EnumOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4944
+	39, // 50: google.protobuf.EnumValueOptions.features:type_name -> google.protobuf.FeatureSet
4945
+	48, // 51: google.protobuf.EnumValueOptions.feature_support:type_name -> google.protobuf.FieldOptions.FeatureSupport
4946
+	38, // 52: google.protobuf.EnumValueOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4947
+	39, // 53: google.protobuf.ServiceOptions.features:type_name -> google.protobuf.FeatureSet
4948
+	38, // 54: google.protobuf.ServiceOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4949
+	10, // 55: google.protobuf.MethodOptions.idempotency_level:type_name -> google.protobuf.MethodOptions.IdempotencyLevel
4950
+	39, // 56: google.protobuf.MethodOptions.features:type_name -> google.protobuf.FeatureSet
4951
+	38, // 57: google.protobuf.MethodOptions.uninterpreted_option:type_name -> google.protobuf.UninterpretedOption
4952
+	49, // 58: google.protobuf.UninterpretedOption.name:type_name -> google.protobuf.UninterpretedOption.NamePart
4953
+	11, // 59: google.protobuf.FeatureSet.field_presence:type_name -> google.protobuf.FeatureSet.FieldPresence
4954
+	12, // 60: google.protobuf.FeatureSet.enum_type:type_name -> google.protobuf.FeatureSet.EnumType
4955
+	13, // 61: google.protobuf.FeatureSet.repeated_field_encoding:type_name -> google.protobuf.FeatureSet.RepeatedFieldEncoding
4956
+	14, // 62: google.protobuf.FeatureSet.utf8_validation:type_name -> google.protobuf.FeatureSet.Utf8Validation
4957
+	15, // 63: google.protobuf.FeatureSet.message_encoding:type_name -> google.protobuf.FeatureSet.MessageEncoding
4958
+	16, // 64: google.protobuf.FeatureSet.json_format:type_name -> google.protobuf.FeatureSet.JsonFormat
4959
+	17, // 65: google.protobuf.FeatureSet.enforce_naming_style:type_name -> google.protobuf.FeatureSet.EnforceNamingStyle
4960
+	18, // 66: google.protobuf.FeatureSet.default_symbol_visibility:type_name -> google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility
4961
+	51, // 67: google.protobuf.FeatureSetDefaults.defaults:type_name -> google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault
4962
+	0,  // 68: google.protobuf.FeatureSetDefaults.minimum_edition:type_name -> google.protobuf.Edition
4963
+	0,  // 69: google.protobuf.FeatureSetDefaults.maximum_edition:type_name -> google.protobuf.Edition
4964
+	52, // 70: google.protobuf.SourceCodeInfo.location:type_name -> google.protobuf.SourceCodeInfo.Location
4965
+	53, // 71: google.protobuf.GeneratedCodeInfo.annotation:type_name -> google.protobuf.GeneratedCodeInfo.Annotation
4966
+	23, // 72: google.protobuf.DescriptorProto.ExtensionRange.options:type_name -> google.protobuf.ExtensionRangeOptions
4967
+	0,  // 73: google.protobuf.FieldOptions.EditionDefault.edition:type_name -> google.protobuf.Edition
4968
+	0,  // 74: google.protobuf.FieldOptions.FeatureSupport.edition_introduced:type_name -> google.protobuf.Edition
4969
+	0,  // 75: google.protobuf.FieldOptions.FeatureSupport.edition_deprecated:type_name -> google.protobuf.Edition
4970
+	0,  // 76: google.protobuf.FieldOptions.FeatureSupport.edition_removed:type_name -> google.protobuf.Edition
4971
+	0,  // 77: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.edition:type_name -> google.protobuf.Edition
4972
+	39, // 78: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.overridable_features:type_name -> google.protobuf.FeatureSet
4973
+	39, // 79: google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault.fixed_features:type_name -> google.protobuf.FeatureSet
4974
+	19, // 80: google.protobuf.GeneratedCodeInfo.Annotation.semantic:type_name -> google.protobuf.GeneratedCodeInfo.Annotation.Semantic
4975
+	81, // [81:81] is the sub-list for method output_type
4976
+	81, // [81:81] is the sub-list for method input_type
4977
+	81, // [81:81] is the sub-list for extension type_name
4978
+	81, // [81:81] is the sub-list for extension extendee
4979
+	0,  // [0:81] is the sub-list for field type_name
4974 4980
 }
4975 4981
 
4976 4982
 func init() { file_google_protobuf_descriptor_proto_init() }
... ...
@@ -4983,8 +5222,8 @@ func file_google_protobuf_descriptor_proto_init() {
4983 4983
 		File: protoimpl.DescBuilder{
4984 4984
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
4985 4985
 			RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_protobuf_descriptor_proto_rawDesc), len(file_google_protobuf_descriptor_proto_rawDesc)),
4986
-			NumEnums:      18,
4987
-			NumMessages:   33,
4986
+			NumEnums:      20,
4987
+			NumMessages:   34,
4988 4988
 			NumExtensions: 0,
4989 4989
 			NumServices:   0,
4990 4990
 		},
... ...
@@ -753,8 +753,8 @@ github.com/mitchellh/hashstructure/v2
753 753
 # github.com/mitchellh/reflectwalk v1.0.2
754 754
 ## explicit
755 755
 github.com/mitchellh/reflectwalk
756
-# github.com/moby/buildkit v0.24.0
757
-## explicit; go 1.23.0
756
+# github.com/moby/buildkit v0.25.0-rc1
757
+## explicit; go 1.24.0
758 758
 github.com/moby/buildkit/api/services/control
759 759
 github.com/moby/buildkit/api/types
760 760
 github.com/moby/buildkit/cache
... ...
@@ -1665,8 +1665,8 @@ google.golang.org/grpc/serviceconfig
1665 1665
 google.golang.org/grpc/stats
1666 1666
 google.golang.org/grpc/status
1667 1667
 google.golang.org/grpc/tap
1668
-# google.golang.org/protobuf v1.36.6
1669
-## explicit; go 1.22
1668
+# google.golang.org/protobuf v1.36.9
1669
+## explicit; go 1.23
1670 1670
 google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo
1671 1671
 google.golang.org/protobuf/compiler/protogen
1672 1672
 google.golang.org/protobuf/encoding/protodelim