code: func (cat *catalog) marshalTask(task proto.Message) ([]byte, error) {
  	if cat.GetTaskManager(task) == nil {
  		return nil, fmt.Errorf("unrecognized task definition type %T", task)
  	}
  	// Enumerate all fields of the wrapper until we find a matching type.
  	taskType := reflect.TypeOf(task)
  	wrapper := messages.TaskDefWrapper{}
  	v := reflect.ValueOf(&wrapper).Elem()
  	for i := 0; i < v.NumField(); i++ {
  		field := v.Field(i)
  		if field.Type() == taskType {
  			field.Set(reflect.ValueOf(task))
  			return proto.Marshal(&wrapper)
  		}
  	}
  	// This can happen only if TaskDefWrapper wasn't updated when a new task type
  	// was added. This is a developer's mistake, not a config mistake.
  	return nil, fmt.Errorf("could not find a field of type %T in TaskDefWrapper", task)
  }
docs: // marshalTask takes a concrete task definition proto (e.g. SwarmingTask), wraps
  // it into TaskDefWrapper proto and marshals this proto. The resulting blob can
  // be sent to UnmarshalTask to get back the task definition proto.