code: func makeDelegationRule(c context.Context, rule *admin.DelegationRule) (*delegationRule, error) {
  	ctx := &validation.Context{Context: c}
  	validateRule(ctx, rule.Name, rule)
  	if err := ctx.Finalize(); err != nil {
  		return nil, err
  	}
  
  	// The main validation step has been done above. Here we just assert that
  	// everything looks sane (it should). See corresponding chunks of
  	// 'ValidateRule' code.
  	requestors, err := identityset.FromStrings(rule.Requestor, nil)
  	if err != nil {
  		panic(err)
  	}
  	delegators, err := identityset.FromStrings(rule.AllowedToImpersonate, skipRequestorOrProjects)
  	if err != nil {
  		panic(err)
  	}
  	audience, err := identityset.FromStrings(rule.AllowedAudience, skipRequestor)
  	if err != nil {
  		panic(err)
  	}
  	services, err := identityset.FromStrings(rule.TargetService, nil)
  	if err != nil {
  		panic(err)
  	}
  
  	return &delegationRule{
  		rule:                    rule,
  		requestors:              requestors,
  		delegators:              delegators,
  		audience:                audience,
  		services:                services,
  		addRequestorAsDelegator: sliceHasString(rule.AllowedToImpersonate, Requestor),
  		addRequestorToAudience:  sliceHasString(rule.AllowedAudience, Requestor),
  		addProjectsAsDelegators: sliceHasString(rule.AllowedToImpersonate, Projects),
  	}, nil
  }
docs: // makeDelegationRule preprocesses admin.DelegationRule proto.
  //
  // It also double checks that the rule is passing validation. The check may
  // fail if new code uses old configs, still stored in the datastore.