code: func assembleClientDigests(ctx context.Context, c cipd.Client, version string) (*digests.ClientDigestsFile, []pinInfo, error) {
  	if !strings.HasSuffix(cipd.ClientPackage, "/${platform}") {
  		panic(fmt.Sprintf("client package template (%q) is expected to end with '${platform}'", cipd.ClientPackage))
  	}
  
  	out := &digests.ClientDigestsFile{}
  	mu := sync.Mutex{}
  
  	// Ask the backend to give us hashes of the client binary for all platforms.
  	pins, err := performBatchOperation(ctx, batchOperation{
  		client:        c,
  		packagePrefix: strings.TrimSuffix(cipd.ClientPackage, "${platform}"),
  		callback: func(pkg string) (common.Pin, error) {
  			pin, err := c.ResolveVersion(ctx, pkg, version)
  			if err != nil {
  				return common.Pin{}, err
  			}
  			desc, err := c.DescribeClient(ctx, pin)
  			if err != nil {
  				return common.Pin{}, err
  			}
  			mu.Lock()
  			defer mu.Unlock()
  			plat := pkg[strings.LastIndex(pkg, "/")+1:]
  			if err := out.AddClientRef(plat, desc.Digest); err != nil {
  				return common.Pin{}, err
  			}
  			return pin, nil
  		},
  	})
  	switch {
  	case err != nil:
  		return nil, pins, err
  	case hasErrors(pins):
  		return nil, pins, errors.New("failed to obtain the client binary digest for all platforms")
  	}
  
  	out.Sort()
  	return out, pins, nil
  }
docs: // assembleClientDigests produces the digests file by making backend RPCs.