code: func modifyTopicIAMPolicy(c context.Context, service *pubsub.Service, topic string, cb func(iamPolicy) error) error {
  	policy, err := service.Projects.Topics.GetIamPolicy(topic).Context(c).Do()
  	if err != nil {
  		return err
  	}
  
  	// Convert the policy to a map. Make a copy to be mutated by the callback.
  	// Need to store the original to detect changes done by the callback.
  	roles := iamPolicyFromBindings(policy.Bindings)
  	clone := roles.clone()
  	if err = cb(clone); err != nil {
  		return err
  	}
  
  	// Skip storing if no changes are made.
  	if clone.isEqual(roles) {
  		return nil
  	}
  
  	// Convert back to IamPolicy struct.
  	logging.Infof(c, "Updating IAM policy of %q", topic)
  	request := &pubsub.SetIamPolicyRequest{
  		Policy: &pubsub.Policy{
  			Bindings: clone.toBindings(),
  			Etag:     policy.Etag,
  		},
  	}
  	_, err = service.Projects.Topics.SetIamPolicy(topic, request).Context(c).Do()
  	return err
  }
docs: // modifyTopicIAMPolicy reads IAM policy, calls callback to modify it, and then
  // puts it back (if callback really changed it).